From 75c29d856dfbb135277ad853248dd3e9b2d559f9 Mon Sep 17 00:00:00 2001 From: Tolga Akyuz Date: Tue, 14 Mar 2017 10:15:54 +0100 Subject: [PATCH 001/192] Space resource is migrated to SDK --- contentful_apikey.go | 3 +- contentful_space.go | 220 ------------------------------ contentful_space_test.go | 126 ----------------- provider.go | 12 +- resource_contentful_space.go | 85 ++++++------ resource_contentful_space_test.go | 42 ++---- 6 files changed, 71 insertions(+), 417 deletions(-) delete mode 100644 contentful_space_test.go diff --git a/contentful_apikey.go b/contentful_apikey.go index 21ce653..ebddc3a 100644 --- a/contentful_apikey.go +++ b/contentful_apikey.go @@ -3,8 +3,9 @@ package main import ( "errors" "fmt" - "github.com/levigross/grequests" "strconv" + + "github.com/levigross/grequests" ) type apiKeyProperties struct { diff --git a/contentful_space.go b/contentful_space.go index b1fcd18..58d3e99 100644 --- a/contentful_space.go +++ b/contentful_space.go @@ -1,13 +1,5 @@ package main -import ( - "errors" - "fmt" - "strconv" - - "github.com/levigross/grequests" -) - type collectionProperties struct { Total int `json:"total"` Limit int `json:"limit"` @@ -44,215 +36,3 @@ type spaceCollection struct { collectionProperties Items []spaceData `json:"items"` } - -func createSpace( - cmaToken string, - organizationID string, - spaceName string, - defaultLocale string, -) (*spaceData, error) { - URL := baseURL + "/spaces/" - res, err := grequests.Post(URL, &grequests.RequestOptions{ - Headers: map[string]string{ - "Authorization": fmt.Sprintf("Bearer %s", cmaToken), - "Content-Type": contentfulContentType, - "X-Contentful-Organization": organizationID, - }, - JSON: map[string]string{ - "name": spaceName, - "defaultLocale": defaultLocale, - }, - }) - if err != nil { - return nil, err - } - defer res.Close() - - if res.StatusCode == 401 { - return nil, errorUnauthorized - } - - if res.StatusCode == 404 { - return nil, errorOrganizationNotFound - } - - if res.StatusCode != 201 { - return nil, errors.New(res.String()) - } - - s := &spaceData{} - if err := res.JSON(s); err != nil { - return nil, err - } - - return s, nil -} - -func updateSpace( - cmaToken string, - spaceID string, - spaceVersion int, - newSpaceName string, -) (*spaceData, error) { - URL := baseURL + "/spaces/" + spaceID - res, err := grequests.Put(URL, &grequests.RequestOptions{ - Headers: map[string]string{ - "Authorization": fmt.Sprintf("Bearer %s", cmaToken), - "Content-Type": contentfulContentType, - "X-Contentful-Version": strconv.Itoa(spaceVersion), - }, - JSON: map[string]string{ - "name": newSpaceName, - }, - }) - if err != nil { - return nil, err - } - defer res.Close() - - if res.StatusCode == 401 { - return nil, errorUnauthorized - } - - // ...Sigh... - if res.StatusCode == 503 { - return nil, errorSpaceNotFound - } - - if res.StatusCode != 200 { - return nil, errors.New(res.String()) - } - - s := &spaceData{} - if err := res.JSON(s); err != nil { - return nil, err - } - - return s, nil -} - -func readSpace(cmaToken, spaceID string) (*spaceData, error) { - URL := baseURL + "/spaces/" + spaceID - res, err := grequests.Get(URL, &grequests.RequestOptions{ - Headers: map[string]string{ - "Authorization": fmt.Sprintf("Bearer %s", cmaToken), - }, - }) - if err != nil { - return nil, err - } - defer res.Close() - - if res.StatusCode == 401 { - return nil, errorUnauthorized - } - - // ...Sigh... The routing returns 503 if a space cannot be found, not 404. - // It's either abiding by the broken status code, or using the /token endpoint, which - // is more accurate but annoying. TODO: Check the /token endpoint - if res.StatusCode == 503 { - return nil, errorSpaceNotFound - } - - if res.StatusCode == 404 { - return nil, errorSpaceNotFound - } - - if res.StatusCode != 200 { - return nil, errors.New(res.String()) - } - - s := &spaceData{} - if err := res.JSON(s); err != nil { - return nil, err - } - - return s, nil -} - -func deleteSpace(cmaToken, spaceID string) error { - URL := baseURL + "/spaces/" + spaceID - res, err := grequests.Delete(URL, &grequests.RequestOptions{ - Headers: map[string]string{ - "Authorization": fmt.Sprintf("Bearer %s", cmaToken), - }, - }) - if err != nil { - return err - } - defer res.Close() - - if res.StatusCode == 401 { - return errorUnauthorized - } - - if res.StatusCode == 404 { - return errorSpaceNotFound - } - - if res.StatusCode != 204 { - return errors.New(res.String()) - } - - return nil -} - -func listSpaces(cmaToken string) ([]spaceData, error) { - URL := baseURL + "/spaces/" - - res, err := grequests.Get(URL, &grequests.RequestOptions{ - Headers: map[string]string{ - "Authorization": "Bearer " + cmaToken, - }, - }) - if err != nil { - return nil, err - } - defer res.Close() - - if res.StatusCode == 401 { - return nil, errorUnauthorized - } - - if res.StatusCode != 200 { - return nil, errors.New(res.String()) - } - - spaceCol := &spaceCollection{} - if err := res.JSON(spaceCol); err != nil { - return nil, err - } - - return spaceCol.Items, nil -} - -func spaceExists( - cmaToken string, - spaceName string, -) (bool, error) { - URL := baseURL + "/spaces/" + spaceName - res, err := grequests.Get(URL, &grequests.RequestOptions{ - Headers: map[string]string{ - "Authorization": fmt.Sprintf("Bearer %s", cmaToken), - "Content-Type": contentfulContentType, - }, - }) - if err != nil { - return false, err - } - defer res.Close() - - if res.StatusCode == 200 { - return true, nil - } - - if res.StatusCode == 401 { - return false, errorUnauthorized - } - - if res.StatusCode != 200 && res.StatusCode != 404 { - return false, errors.New(res.String()) - } - - return false, nil -} diff --git a/contentful_space_test.go b/contentful_space_test.go deleted file mode 100644 index 7048d12..0000000 --- a/contentful_space_test.go +++ /dev/null @@ -1,126 +0,0 @@ -package main - -import ( - "encoding/json" - "net/http" - "net/http/httptest" - "strconv" - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestCreateSpace(t *testing.T) { - cmaToken := "test-token" - // TODO: If only one org, create without requiring orgID. Two tests - organizationID := "test-organization" - spaceName := "test-name" - defaultLocale := "en" - - serveFn := func(w http.ResponseWriter, req *http.Request) { - assert.Equal(t, req.Method, "POST") - assert.Equal(t, req.RequestURI, "/spaces/") - assert.Equal(t, "Bearer "+cmaToken, req.Header.Get("Authorization")) - assert.Equal(t, "application/vnd.contentful.management.v1+json", req.Header.Get("Content-Type")) - assert.Equal(t, organizationID, req.Header.Get("X-Contentful-Organization")) - - var payload map[string]string - assert.Nil(t, json.NewDecoder(req.Body).Decode(&payload)) - assert.Equal(t, spaceName, payload["name"]) - assert.Equal(t, defaultLocale, payload["defaultLocale"]) - - w.WriteHeader(201) - err := json.NewEncoder(w).Encode(&spaceData{}) - assert.Nil(t, err) - } - - server := httptest.NewServer(&testHandler{handleFunc: serveFn}) - defer server.Close() - baseURL = server.URL - - _, err := createSpace(cmaToken, organizationID, spaceName, defaultLocale) - assert.Nil(t, err) -} - -func TestUpdateSpace(t *testing.T) { - cmaToken := "test-token" - spaceID := "test-space" - version := 1 - newSpaceName := "test-name" - - serveFn := func(w http.ResponseWriter, req *http.Request) { - assert.Equal(t, req.Method, "PUT") - assert.Equal(t, req.RequestURI, "/spaces/"+spaceID) - assert.Equal(t, "Bearer "+cmaToken, req.Header.Get("Authorization")) - assert.Equal(t, "application/vnd.contentful.management.v1+json", req.Header.Get("Content-Type")) - assert.Equal(t, strconv.Itoa(version), req.Header.Get("X-Contentful-Version")) - - var payload map[string]string - assert.Nil(t, json.NewDecoder(req.Body).Decode(&payload)) - assert.Equal(t, newSpaceName, payload["name"]) - - w.WriteHeader(200) - err := json.NewEncoder(w).Encode(&spaceData{}) - assert.Nil(t, err) - } - - server := httptest.NewServer(&testHandler{handleFunc: serveFn}) - defer server.Close() - baseURL = server.URL - - _, err := updateSpace(cmaToken, spaceID, version, newSpaceName) - assert.Nil(t, err) -} - -func TestReadSpace(t *testing.T) { - cmaToken := "test-token" - spaceID := "test-space" - - serveFn := func(w http.ResponseWriter, req *http.Request) { - assert.Equal(t, req.Method, "GET") - assert.Equal(t, req.RequestURI, "/spaces/"+spaceID) - assert.Equal(t, "Bearer "+cmaToken, req.Header.Get("Authorization")) - - w.WriteHeader(200) - err := json.NewEncoder(w).Encode(&spaceData{}) - assert.Nil(t, err) - } - - server := httptest.NewServer(&testHandler{handleFunc: serveFn}) - defer server.Close() - baseURL = server.URL - - _, err := readSpace(cmaToken, spaceID) - assert.Nil(t, err) -} - -func TestDeleteSpace(t *testing.T) { - cmaToken := "test-token" - spaceID := "test-space" - - serveFn := func(w http.ResponseWriter, req *http.Request) { - assert.Equal(t, req.Method, "DELETE") - assert.Equal(t, req.RequestURI, "/spaces/"+spaceID) - assert.Equal(t, "Bearer "+cmaToken, req.Header.Get("Authorization")) - - w.WriteHeader(204) - } - - server := httptest.NewServer(&testHandler{handleFunc: serveFn}) - defer server.Close() - baseURL = server.URL - - err := deleteSpace(cmaToken, spaceID) - assert.Nil(t, err) -} - -type httpClientMock struct { - passedInRequest *http.Request - returnedResponse *http.Response - returnedError error -} - -func (c *httpClientMock) Do(req *http.Request) (*http.Response, error) { - c.passedInRequest = req - return c.returnedResponse, c.returnedError -} diff --git a/provider.go b/provider.go index 4681ea0..b3a3e05 100644 --- a/provider.go +++ b/provider.go @@ -3,6 +3,7 @@ package main import ( "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/terraform" + contentful "github.com/tolgaakyuz/contentful.go" ) // Provider does shit @@ -33,9 +34,18 @@ func Provider() terraform.ResourceProvider { } func providerConfigure(d *schema.ResourceData) (interface{}, error) { - config := map[string]string{ + c, err := contentful.New(&contentful.Settings{ + CMAToken: d.Get("cma_token").(string), + }) + if err != nil { + return nil, err + } + + config := map[string]interface{}{ "cma_token": d.Get("cma_token").(string), "organization_id": d.Get("organization_id").(string), + "client": c, } + return config, nil } diff --git a/resource_contentful_space.go b/resource_contentful_space.go index 7cf875a..354c882 100644 --- a/resource_contentful_space.go +++ b/resource_contentful_space.go @@ -2,7 +2,7 @@ package main import ( "github.com/hashicorp/terraform/helper/schema" - "log" + contentful "github.com/tolgaakyuz/contentful.go" ) func resourceContentfulSpace() *schema.Resource { @@ -35,83 +35,90 @@ func resourceContentfulSpace() *schema.Resource { } } -func resourceSpaceCreate(d *schema.ResourceData, m interface{}) error { - configMap := m.(map[string]string) - name := d.Get("name").(string) - defaultLocale := d.Get("default_locale").(string) - - spacejson, err := createSpace( - configMap["cma_token"], - configMap["organization_id"], - name, - defaultLocale, - ) +func resourceSpaceCreate(d *schema.ResourceData, m interface{}) (err error) { + configMap := m.(map[string]interface{}) + client := configMap["client"].(*contentful.Contentful) + space := client.NewSpace(configMap["organization_id"].(string)) + space.Name = d.Get("name").(string) + space.DefaultLocale = d.Get("default_locale").(string) + err = space.Save() if err != nil { return err } - err = updateSpaceProperties(d, spacejson) + err = updateSpaceProperties(d, space) if err != nil { return err } - d.SetId(spacejson.Sys.ID) + d.SetId(space.Sys.ID) + return nil } func resourceSpaceRead(d *schema.ResourceData, m interface{}) error { - configMap := m.(map[string]string) - _, err := readSpace(configMap["cma_token"], d.Id()) + configMap := m.(map[string]interface{}) - log.Println("big problums", err == errorSpaceNotFound) + client := configMap["client"].(*contentful.Contentful) + _, err := client.GetSpace(d.Id()) - if err == errorSpaceNotFound { + switch t := err.(type) { + case contentful.NotFoundError: d.SetId("") return nil - } - - if err != nil { + default: + _ = t return err } - - return nil } -func resourceSpaceUpdate(d *schema.ResourceData, m interface{}) error { - configMap := m.(map[string]string) - spaceVersion := d.Get("version").(int) - newSpaceName := d.Get("name").(string) - log.Println("spaceVersion", spaceVersion) +func resourceSpaceUpdate(d *schema.ResourceData, m interface{}) (err error) { + configMap := m.(map[string]interface{}) - spacejson, err := updateSpace(configMap["cma_token"], d.Id(), spaceVersion, newSpaceName) + client := configMap["client"].(*contentful.Contentful) + space, err := client.GetSpace(d.Id()) + if err != nil { + return err + } + space.Name = d.Get("name").(string) + // space.Sys.Version = d.Get("version").(int) + err = space.Save() if err != nil { return err } - return updateSpaceProperties(d, spacejson) + return updateSpaceProperties(d, space) } -func resourceSpaceDelete(d *schema.ResourceData, m interface{}) error { - configMap := m.(map[string]string) +func resourceSpaceDelete(d *schema.ResourceData, m interface{}) (err error) { + configMap := m.(map[string]interface{}) + + client := configMap["client"].(*contentful.Contentful) + space, err := client.GetSpace(d.Id()) + if err != nil { + return err + } - err := deleteSpace(configMap["cma_token"], d.Id()) + err = space.Delete() - if err == errorSpaceNotFound { + switch t := err.(type) { + case contentful.NotFoundError: return nil + default: + _ = t + return err } - - return err } -func updateSpaceProperties(d *schema.ResourceData, spacejson *spaceData) error { - err := d.Set("version", spacejson.Sys.Version) +func updateSpaceProperties(d *schema.ResourceData, space *contentful.Space) error { + err := d.Set("version", space.Sys.Version) if err != nil { return err } - err = d.Set("name", spacejson.Name) + err = d.Set("name", space.Name) if err != nil { return err } diff --git a/resource_contentful_space_test.go b/resource_contentful_space_test.go index 9efef03..4838c4a 100644 --- a/resource_contentful_space_test.go +++ b/resource_contentful_space_test.go @@ -1,12 +1,12 @@ package main import ( - "errors" "fmt" "testing" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" + contentful "github.com/tolgaakyuz/contentful.go" ) func TestAccContentfulSpace_Basic(t *testing.T) { @@ -25,47 +25,29 @@ func TestAccContentfulSpace_Basic(t *testing.T) { } func testAccCheckContentfulSpaceDestroy(s *terraform.State) error { - configMap := testAccProvider.Meta().(map[string]string) + configMap := testAccProvider.Meta().(map[string]interface{}) for _, rs := range s.RootModule().Resources { if rs.Type != "contentful_space" { continue } - exists, err := spaceExists(configMap["cma_token"], rs.Primary.ID) - - if err != nil { - return fmt.Errorf("Error checking space %s: %s", rs.Primary.ID, err) - } - - if exists { + client := configMap["client"].(*contentful.Contentful) + _, err := client.GetSpace(rs.Primary.ID) + if err == nil { return fmt.Errorf("Space %s still exists after destroy", rs.Primary.ID) } - } - - return nil -} - -func testAccCheckContentfulSpaceExists(n string) resource.TestCheckFunc { - return func(s *terraform.State) error { - rs, ok := s.RootModule().Resources[n] - if !ok { - return fmt.Errorf("Resource not found: %s", n) - } - - if rs.Primary.ID == "" { - return errors.New("No ID is set") - } - configMap := testAccProvider.Meta().(map[string]string) - _, err := spaceExists(configMap["cma_token"], rs.Primary.ID) - - if err != nil { + switch t := err.(type) { + case contentful.NotFoundError: + return nil + default: + _ = t return fmt.Errorf("Error checking space %s: %s", rs.Primary.ID, err) - } - return nil } + + return nil } var testAccCheckContentfulSpaceConfig = ` From 4c2500f7a638e80ba47fa48934723604fcff5637 Mon Sep 17 00:00:00 2001 From: Tolga Akyuz Date: Tue, 14 Mar 2017 13:55:26 +0100 Subject: [PATCH 002/192] Locale resource migration --- contentful_locale.go | 196 ---------------------------------- resource_contentful_locale.go | 124 ++++++++++++--------- 2 files changed, 71 insertions(+), 249 deletions(-) delete mode 100644 contentful_locale.go diff --git a/contentful_locale.go b/contentful_locale.go deleted file mode 100644 index 9738f3e..0000000 --- a/contentful_locale.go +++ /dev/null @@ -1,196 +0,0 @@ -package main - -import ( - "encoding/json" - "errors" - "fmt" - "log" - - "github.com/levigross/grequests" -) - -type localeProperties struct { - Name string `json:"name"` - Code string `json:"code"` - FallbackCode string `json:"fallbackCode"` - Optional bool `json:"optional"` -} - -type locale struct { - spaceEntitySys - localeProperties -} - -func localePath(baseURL, spaceID, localeID string) string { - return fmt.Sprintf("%s/spaces/%s/locales/%s", baseURL, spaceID, localeID) -} - -func readLocale(cmaToken, spaceID, localeID string) (*locale, error) { - path := localePath(baseURL, spaceID, localeID) - authHeader := fmt.Sprintf("Bearer %s", cmaToken) - - res, err := grequests.Get(path, &grequests.RequestOptions{ - Headers: map[string]string{ - "Authorization": authHeader, - }, - }) - - if err != nil { - return nil, err - } - - if res.StatusCode == 401 { - return nil, errorUnauthorized - } - - // ...Sigh... The routing returns 503 if a space cannot be found, not 404. - // It's either abiding by the broken status code, or using the /token endpoint, which - // is more accurate but annoying. TODO: Check the /token endpoint - if res.StatusCode == 503 { - return nil, errorSpaceNotFound - } - - if res.StatusCode == 404 { - return nil, errorLocaleNotFound - } - - if res.StatusCode != 200 { - return nil, errors.New(res.String()) - } - - var json locale - if err := res.JSON(&json); err != nil { - return nil, err - } - - return &json, nil -} - -func createLocale( - cmaToken string, - spaceID string, - localeProps localeProperties, -) (*locale, error) { - - path := localePath(baseURL, spaceID, "") - authHeader := fmt.Sprintf("Bearer %s", cmaToken) - - res, err := grequests.Post(path, &grequests.RequestOptions{ - Headers: map[string]string{ - "Authorization": authHeader, - "Content-Type": "application/vnd.contentful.management.v1+json", - }, - JSON: localeProps, - }) - - if err != nil { - return nil, err - } - - if res.StatusCode == 401 { - return nil, errorUnauthorized - } - - if res.StatusCode == 404 { - return nil, errorSpaceNotFound - } - - if res.StatusCode != 200 { - - log.Println("path", path) - log.Println("status code", res.StatusCode) - log.Printf("dickhead %+v\n", localeProps) - b, _ := json.Marshal(localeProps) - log.Println(string(b)) - log.Println(path) - - return nil, errors.New(res.String()) - } - - var json locale - if err := res.JSON(&json); err != nil { - return nil, err - } - - return &json, nil -} - -func updateLocale( - cmaToken string, - spaceID string, - localeID string, - localeProps localeProperties, -) (*locale, error) { - - path := localePath(baseURL, spaceID, "") - authHeader := fmt.Sprintf("Bearer %s", cmaToken) - - res, err := grequests.Put(path, &grequests.RequestOptions{ - Headers: map[string]string{ - "Authorization": authHeader, - "Content-Type": "application/vnd.contentful.management.v1+json", - }, - JSON: localeProps, - }) - - if err != nil { - return nil, err - } - - if res.StatusCode == 401 { - return nil, errorUnauthorized - } - - if res.StatusCode == 404 { - return nil, errorSpaceNotFound - } - - if res.StatusCode != 200 { - - log.Println("path", path) - log.Println("status code", res.StatusCode) - log.Printf("dickhead %+v\n", localeProps) - b, _ := json.Marshal(localeProps) - log.Println(string(b)) - log.Println(path) - - return nil, errors.New(res.String()) - } - - var json locale - if err := res.JSON(&json); err != nil { - return nil, err - } - - return &json, nil -} - -func deleteLocale(cmaToken, spaceID, localeID string) error { - path := localePath(baseURL, spaceID, localeID) - authHeader := fmt.Sprintf("Bearer %s", cmaToken) - - res, err := grequests.Delete(path, &grequests.RequestOptions{ - Headers: map[string]string{ - "Authorization": authHeader, - }, - }) - - if err != nil { - return err - } - - if res.StatusCode == 401 { - return errorUnauthorized - } - - if res.StatusCode == 404 { - return errorSpaceNotFound - } - - if res.StatusCode != 204 { - msg := fmt.Sprintf("Error: unknown status code: %d", res.StatusCode) - return errors.New(msg) - } - - return nil -} diff --git a/resource_contentful_locale.go b/resource_contentful_locale.go index 0f25913..056b4d6 100644 --- a/resource_contentful_locale.go +++ b/resource_contentful_locale.go @@ -2,6 +2,7 @@ package main import ( "github.com/hashicorp/terraform/helper/schema" + contentful "github.com/tolgaakyuz/contentful.go" ) func resourceContentfulLocale() *schema.Resource { @@ -47,76 +48,82 @@ func resourceContentfulLocale() *schema.Resource { } } -func resourceCreateLocale(d *schema.ResourceData, m interface{}) error { - configMap := m.(map[string]string) - cmaToken := configMap["cma_token"] - spaceID := d.Get("space_id").(string) +func resourceCreateLocale(d *schema.ResourceData, m interface{}) (err error) { + configMap := m.(map[string]interface{}) + client := configMap["client"].(*contentful.Contentful) - localeProps := localeProperties{ - Name: d.Get("name").(string), - Code: d.Get("code").(string), - FallbackCode: d.Get("fallback_code").(string), - Optional: d.Get("optional").(bool), + space, err := client.GetSpace(d.Get("space_id").(string)) + if err != nil { + return err } - loc, err := createLocale( - cmaToken, - spaceID, - localeProps, - ) + locale := space.NewLocale() + locale.Name = d.Get("name").(string) + locale.Code = d.Get("code").(string) + locale.FallbackCode = d.Get("fallback_code").(string) + locale.Optional = d.Get("optional").(bool) + + err = locale.Save() if err != nil { return err } - err = setLocaleProperties(d, loc) + err = setLocaleProperties(d, locale) if err != nil { return err } - d.SetId(loc.Sys.ID) + d.SetId(locale.Sys.ID) + return nil } func resourceReadLocale(d *schema.ResourceData, m interface{}) error { - configMap := m.(map[string]string) - cmaToken := configMap["cma_token"] - spaceID := d.Get("space_id").(string) - localeID := d.Id() + configMap := m.(map[string]interface{}) + client := configMap["client"].(*contentful.Contentful) - loc, err := readLocale(cmaToken, spaceID, localeID) + space, err := client.GetSpace(d.Get("space_id").(string)) + if err != nil { + return err + } - if err == errorLocaleNotFound { + locale, err := space.GetLocale(d.Id()) + if _, ok := err.(*contentful.NotFoundError); ok { d.SetId("") return nil } - return setLocaleProperties(d, loc) + if err != nil { + return err + } + + return setLocaleProperties(d, locale) } -func resourceUpdateLocale(d *schema.ResourceData, m interface{}) error { - configMap := m.(map[string]string) - cmaToken := configMap["cma_token"] - spaceID := d.Get("space_id").(string) - localeID := d.Id() +func resourceUpdateLocale(d *schema.ResourceData, m interface{}) (err error) { + configMap := m.(map[string]interface{}) + client := configMap["client"].(*contentful.Contentful) - localeProps := localeProperties{ - Name: d.Get("name").(string), - Code: d.Get("code").(string), - FallbackCode: d.Get("fallback_code").(string), - Optional: d.Get("optional").(bool), + space, err := client.GetSpace(d.Get("space_id").(string)) + if err != nil { + return err } - loc, err := updateLocale( - cmaToken, - spaceID, - localeID, - localeProps, - ) + locale, err := space.GetLocale(d.Id()) if err != nil { return err } - err = setLocaleProperties(d, loc) + locale.Name = d.Get("name").(string) + locale.Code = d.Get("code").(string) + locale.FallbackCode = d.Get("fallback_code").(string) + locale.Optional = d.Get("optional").(bool) + err = locale.Save() + if err != nil { + return err + } + + err = setLocaleProperties(d, locale) if err != nil { return err } @@ -124,38 +131,49 @@ func resourceUpdateLocale(d *schema.ResourceData, m interface{}) error { return nil } -func resourceDeleteLocale(d *schema.ResourceData, m interface{}) error { - configMap := m.(map[string]string) - cmaToken := configMap["cma_token"] - spaceID := d.Get("space_id").(string) - localeID := d.Id() +func resourceDeleteLocale(d *schema.ResourceData, m interface{}) (err error) { + configMap := m.(map[string]interface{}) + client := configMap["client"].(*contentful.Contentful) - err := deleteLocale(cmaToken, spaceID, localeID) + space, err := client.GetSpace(d.Get("space_id").(string)) + if err != nil { + return err + } + + locale, err := space.GetLocale(d.Id()) + if err != nil { + return err + } - if err == errorLocaleNotFound { + err = locale.Delete() + if _, ok := err.(*contentful.NotFoundError); ok { return nil } - return err + if err != nil { + return err + } + + return nil } -func setLocaleProperties(d *schema.ResourceData, loc *locale) error { - err := d.Set("name", loc.Name) +func setLocaleProperties(d *schema.ResourceData, locale *contentful.Locale) error { + err := d.Set("name", locale.Name) if err != nil { return err } - err = d.Set("code", loc.Code) + err = d.Set("code", locale.Code) if err != nil { return err } - err = d.Set("fallbackCode", loc.FallbackCode) + err = d.Set("fallbackCode", locale.FallbackCode) if err != nil { return err } - err = d.Set("optional", loc.Optional) + err = d.Set("optional", locale.Optional) if err != nil { return err } From 3d8da545e011a726f2980320b331b08ea0bf00ec Mon Sep 17 00:00:00 2001 From: Tolga Akyuz Date: Tue, 14 Mar 2017 13:58:12 +0100 Subject: [PATCH 003/192] error type check --- resource_contentful_space.go | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/resource_contentful_space.go b/resource_contentful_space.go index 354c882..0f9ebce 100644 --- a/resource_contentful_space.go +++ b/resource_contentful_space.go @@ -63,14 +63,12 @@ func resourceSpaceRead(d *schema.ResourceData, m interface{}) error { client := configMap["client"].(*contentful.Contentful) _, err := client.GetSpace(d.Id()) - switch t := err.(type) { - case contentful.NotFoundError: + if _, ok := err.(contentful.NotFoundError); ok { d.SetId("") return nil - default: - _ = t - return err } + + return err } func resourceSpaceUpdate(d *schema.ResourceData, m interface{}) (err error) { @@ -103,13 +101,11 @@ func resourceSpaceDelete(d *schema.ResourceData, m interface{}) (err error) { err = space.Delete() - switch t := err.(type) { - case contentful.NotFoundError: + if _, ok := err.(contentful.NotFoundError); ok { return nil - default: - _ = t - return err } + + return err } func updateSpaceProperties(d *schema.ResourceData, space *contentful.Space) error { From a301fb1e06d7bd7111904b643ba0c53789272bed Mon Sep 17 00:00:00 2001 From: Tolga Akyuz Date: Tue, 14 Mar 2017 14:37:59 +0100 Subject: [PATCH 004/192] ApiKey is migrated to SDK --- contentful_apikey.go | 180 ---------------------------------- contentful_apikey_test.go | 116 ---------------------- resource_contentful_apikey.go | 101 ++++++++++++------- 3 files changed, 63 insertions(+), 334 deletions(-) delete mode 100644 contentful_apikey.go delete mode 100644 contentful_apikey_test.go diff --git a/contentful_apikey.go b/contentful_apikey.go deleted file mode 100644 index ebddc3a..0000000 --- a/contentful_apikey.go +++ /dev/null @@ -1,180 +0,0 @@ -package main - -import ( - "errors" - "fmt" - "strconv" - - "github.com/levigross/grequests" -) - -type apiKeyProperties struct { - Name string `json:"name"` - Description string `json:"description"` - AccessToken string `json:"accessToken"` - Policies []struct { - Effect string `json:"effect"` - Actions string `json:"actions"` - } `json:"policies"` - PreviewAPIKey link `json:"preview_api_key"` -} - -type apiKeyData struct { - spaceEntitySys - apiKeyProperties -} - -type apiKeyCollection struct { - collectionProperties - Items []apiKeyData `json:"items"` -} - -func apiKeyURL(baseURL, spaceID, apiKeyID string) string { - return fmt.Sprintf("%s/spaces/%s/api_keys/%s", baseURL, spaceID, apiKeyID) -} - -func createAPIKey(cmaToken, spaceID, name string) (*apiKeyData, error) { - URL := apiKeyURL(baseURL, spaceID, "") - res, err := grequests.Post(URL, &grequests.RequestOptions{ - Headers: map[string]string{ - "Authorization": fmt.Sprintf("Bearer %s", cmaToken), - "Content-Type": contentfulContentType, - }, - JSON: map[string]string{ - "name": name, - }, - }) - if err != nil { - return nil, err - } - defer res.Close() - - if res.StatusCode == 401 { - return nil, errorUnauthorized - } - - if res.StatusCode != 201 { - return nil, errors.New(res.String()) - } - - key := &apiKeyData{} - if err := res.JSON(key); err != nil { - return nil, err - } - - return key, nil -} - -func updateAPIKey( - cmaToken, - spaceID, - apiKeyID string, - version int, - newName string, -) (*apiKeyData, error) { - URL := apiKeyURL(baseURL, spaceID, apiKeyID) - res, err := grequests.Put(URL, &grequests.RequestOptions{ - Headers: map[string]string{ - "Authorization": fmt.Sprintf("Bearer %s", cmaToken), - "Content-Type": contentfulContentType, - "X-Contentful-Version": strconv.Itoa(version), - }, - JSON: map[string]string{ - "name": newName, - }, - }) - if err != nil { - return nil, err - } - defer res.Close() - - if res.StatusCode == 401 { - return nil, errorUnauthorized - } - - if res.StatusCode != 200 { - return nil, errors.New(res.String()) - } - - key := &apiKeyData{} - if err := res.JSON(key); err != nil { - return nil, err - } - - return key, nil -} - -func readAPIKey(cmaToken, spaceID, apiKeyID string) (*apiKeyData, error) { - URL := apiKeyURL(baseURL, spaceID, apiKeyID) - res, err := grequests.Get(URL, &grequests.RequestOptions{ - Headers: map[string]string{ - "Authorization": fmt.Sprintf("Bearer %s", cmaToken), - }, - }) - if err != nil { - return nil, err - } - defer res.Close() - - if res.StatusCode == 401 { - return nil, errorUnauthorized - } - - if res.StatusCode != 200 { - return nil, errors.New(res.String()) - } - - key := &apiKeyData{} - if err := res.JSON(key); err != nil { - return nil, err - } - - return key, nil -} - -func deleteAPIKey(cmaToken, spaceID, apiKeyID string) error { - URL := apiKeyURL(baseURL, spaceID, apiKeyID) - res, err := grequests.Delete(URL, &grequests.RequestOptions{ - Headers: map[string]string{ - "Authorization": fmt.Sprintf("Bearer %s", cmaToken), - }, - }) - if err != nil { - return err - } - defer res.Close() - - if res.StatusCode != 204 { - return errors.New(res.String()) - } - - return nil -} - -func listAPIKeys(cmaToken, spaceID string) ([]apiKeyData, error) { - URL := apiKeyURL(baseURL, spaceID, "") - - resp, err := grequests.Get(URL, &grequests.RequestOptions{ - Headers: map[string]string{ - "Authorization": "Bearer " + cmaToken, - }, - }) - if err != nil { - return nil, err - } - - if resp.StatusCode == 401 { - return nil, errorUnauthorized - } - - if resp.StatusCode != 200 { - return nil, errors.New(resp.String()) - } - - col := &apiKeyCollection{} - if err := resp.JSON(col); err != nil { - return nil, err - } - - return col.Items, nil -} diff --git a/contentful_apikey_test.go b/contentful_apikey_test.go deleted file mode 100644 index 6259ff2..0000000 --- a/contentful_apikey_test.go +++ /dev/null @@ -1,116 +0,0 @@ -package main - -import ( - "encoding/json" - "net/http" - "net/http/httptest" - "strconv" - "testing" - - // "github.com/parnurzeal/gorequest" - "github.com/stretchr/testify/assert" -) - -func TestCreateApikey(t *testing.T) { - cmaToken := "test-token" - spaceID := "test-space" - apikeyName := "test-apikey" - - serveFn := func(w http.ResponseWriter, req *http.Request) { - assert.Equal(t, req.Method, "POST") - assert.Equal(t, req.RequestURI, "/spaces/"+spaceID+"/api_keys/") - assert.Equal(t, "Bearer "+cmaToken, req.Header.Get("Authorization")) - assert.Equal(t, "application/vnd.contentful.management.v1+json", req.Header.Get("Content-Type")) - - var payload map[string]string - assert.Nil(t, json.NewDecoder(req.Body).Decode(&payload)) - assert.Equal(t, apikeyName, payload["name"]) - - w.WriteHeader(201) - err := json.NewEncoder(w).Encode(&apiKeyData{}) - assert.Nil(t, err) - } - - server := httptest.NewServer(&testHandler{handleFunc: serveFn}) - defer server.Close() - baseURL = server.URL - - _, err := createAPIKey(cmaToken, spaceID, apikeyName) - assert.Nil(t, err) -} - -func TestUpdateApikey(t *testing.T) { - cmaToken := "test-token" - spaceID := "test-space" - apiKeyID := "test-apikey" - newAPIKeyName := "test-apikey" - version := 1 - - serveFn := func(w http.ResponseWriter, req *http.Request) { - assert.Equal(t, req.Method, "PUT") - assert.Equal(t, req.RequestURI, "/spaces/"+spaceID+"/api_keys/"+apiKeyID) - assert.Equal(t, "Bearer "+cmaToken, req.Header.Get("Authorization")) - assert.Equal(t, "application/vnd.contentful.management.v1+json", req.Header.Get("Content-Type")) - assert.Equal(t, strconv.Itoa(version), req.Header.Get("X-Contentful-Version")) - - var payload map[string]string - assert.Nil(t, json.NewDecoder(req.Body).Decode(&payload)) - assert.Equal(t, newAPIKeyName, payload["name"]) - - w.WriteHeader(200) - err := json.NewEncoder(w).Encode(&apiKeyData{}) - assert.Nil(t, err) - } - - server := httptest.NewServer(&testHandler{handleFunc: serveFn}) - defer server.Close() - baseURL = server.URL - - _, err := updateAPIKey(cmaToken, spaceID, apiKeyID, version, newAPIKeyName) - assert.Nil(t, err) -} - -func TestReadApikey(t *testing.T) { - cmaToken := "test-token" - spaceID := "test-space" - apiKeyID := "test-id" - - serveFn := func(w http.ResponseWriter, req *http.Request) { - assert.Equal(t, req.Method, "GET") - assert.Equal(t, req.RequestURI, "/spaces/"+spaceID+"/api_keys/"+apiKeyID) - assert.Equal(t, "Bearer "+cmaToken, req.Header.Get("Authorization")) - - w.WriteHeader(200) - err := json.NewEncoder(w).Encode(&apiKeyData{}) - assert.Nil(t, err) - } - - server := httptest.NewServer(&testHandler{handleFunc: serveFn}) - defer server.Close() - baseURL = server.URL - - _, err := readAPIKey(cmaToken, spaceID, apiKeyID) - assert.Nil(t, err) -} - -func TestDeleteApikey(t *testing.T) { - cmaToken := "test-token" - spaceID := "test-space" - apiKeyID := "test-id" - - serveFn := func(w http.ResponseWriter, req *http.Request) { - assert.Equal(t, req.Method, "DELETE") - assert.Equal(t, req.RequestURI, "/spaces/"+spaceID+"/api_keys/"+apiKeyID) - assert.Equal(t, "Bearer "+cmaToken, req.Header.Get("Authorization")) - - w.WriteHeader(204) - } - - server := httptest.NewServer(&testHandler{handleFunc: serveFn}) - defer server.Close() - baseURL = server.URL - - err := deleteAPIKey(cmaToken, spaceID, apiKeyID) - assert.Nil(t, err) - -} diff --git a/resource_contentful_apikey.go b/resource_contentful_apikey.go index 9984eec..62c2443 100644 --- a/resource_contentful_apikey.go +++ b/resource_contentful_apikey.go @@ -2,6 +2,7 @@ package main import ( "github.com/hashicorp/terraform/helper/schema" + contentful "github.com/tolgaakyuz/contentful.go" ) func resourceContentfulAPIKey() *schema.Resource { @@ -41,89 +42,113 @@ func resourceContentfulAPIKey() *schema.Resource { } } -func resourceCreateAPIKey(d *schema.ResourceData, m interface{}) error { - configMap := m.(map[string]string) - cmaToken := configMap["cma_token"] - spaceID := d.Get("space_id").(string) - apiKeyName := d.Get("name").(string) +func resourceCreateAPIKey(d *schema.ResourceData, m interface{}) (err error) { + configMap := m.(map[string]interface{}) + client := configMap["client"].(*contentful.Contentful) - key, err := createAPIKey(cmaToken, spaceID, apiKeyName) + space, err := client.GetSpace(d.Get("space_id").(string)) if err != nil { return err } - if err := setAPIKeyProperties(d, key); err != nil { + apiKey := space.NewAPIKey() + apiKey.Name = d.Get("name").(string) + err = apiKey.Save() + if err != nil { + return err + } + + if err := setAPIKeyProperties(d, apiKey); err != nil { return err } - d.SetId(key.Sys.ID) + d.SetId(apiKey.Sys.ID) + return nil } -func resourceUpdateAPIKey(d *schema.ResourceData, m interface{}) error { - configMap := m.(map[string]string) - cmaToken := configMap["cma_token"] - spaceID := d.Get("space_id").(string) - ID := d.Id() - version := d.Get("version").(int) - newAPIKeyName := d.Get("name").(string) +func resourceUpdateAPIKey(d *schema.ResourceData, m interface{}) (err error) { + configMap := m.(map[string]interface{}) + client := configMap["client"].(*contentful.Contentful) + + space, err := client.GetSpace(d.Get("space_id").(string)) + if err != nil { + return err + } + + apiKey, err := space.GetAPIKey(d.Id()) + if err != nil { + return err + } - key, err := updateAPIKey(cmaToken, spaceID, ID, version, newAPIKeyName) + apiKey.Name = d.Get("name").(string) + err = apiKey.Save() if err != nil { return err } - if err := setAPIKeyProperties(d, key); err != nil { + if err := setAPIKeyProperties(d, apiKey); err != nil { return err } - d.SetId(key.Sys.ID) + d.SetId(apiKey.Sys.ID) + return nil } -func resourceReadAPIKey(d *schema.ResourceData, m interface{}) error { - configMap := m.(map[string]string) - cmaToken := configMap["cma_token"] - spaceID := d.Get("space_id").(string) - ID := d.Id() - - key, err := readAPIKey(cmaToken, spaceID, ID) +func resourceReadAPIKey(d *schema.ResourceData, m interface{}) (err error) { + configMap := m.(map[string]interface{}) + client := configMap["client"].(*contentful.Contentful) + space, err := client.GetSpace(d.Get("space_id").(string)) if err != nil { + return err + } + + apiKey, err := space.GetAPIKey(d.Id()) + if _, ok := err.(contentful.NotFoundError); ok { d.SetId("") return nil } - return setAPIKeyProperties(d, key) + return setAPIKeyProperties(d, apiKey) } -func resourceDeleteAPIKey(d *schema.ResourceData, m interface{}) error { - configMap := m.(map[string]string) - cmaToken := configMap["cma_token"] - spaceID := d.Get("space_id").(string) - ID := d.Id() +func resourceDeleteAPIKey(d *schema.ResourceData, m interface{}) (err error) { + configMap := m.(map[string]interface{}) + client := configMap["client"].(*contentful.Contentful) + + space, err := client.GetSpace(d.Get("space_id").(string)) + if err != nil { + return err + } + + apiKey, err := space.GetAPIKey(d.Id()) + if err != nil { + return err + } - return deleteAPIKey(cmaToken, spaceID, ID) + return apiKey.Delete() } -func setAPIKeyProperties(d *schema.ResourceData, key *apiKeyData) error { - if err := d.Set("space_id", key.Sys.Space.Sys.ID); err != nil { +func setAPIKeyProperties(d *schema.ResourceData, apiKey *contentful.APIKey) error { + if err := d.Set("space_id", apiKey.Sys.Space.Sys.ID); err != nil { return err } - if err := d.Set("version", key.Sys.Version); err != nil { + if err := d.Set("version", apiKey.Sys.Version); err != nil { return err } - if err := d.Set("name", key.Name); err != nil { + if err := d.Set("name", apiKey.Name); err != nil { return err } - if err := d.Set("delivery_api_key", key.AccessToken); err != nil { + if err := d.Set("delivery_api_key", apiKey.AccessToken); err != nil { return err } - if err := d.Set("preview_api_key", key.PreviewAPIKey.Sys.ID); err != nil { + if err := d.Set("preview_api_key", apiKey.PreviewAPIKey.Sys.ID); err != nil { return err } From 14eb6767fa363c22f55360bce8131428507b4828 Mon Sep 17 00:00:00 2001 From: Tolga Akyuz Date: Tue, 14 Mar 2017 15:56:28 +0100 Subject: [PATCH 005/192] webhook resource sdk integration --- contentful_webhook.go | 249 --------------------------------- contentful_webhook_test.go | 142 ------------------- resource_contentful_webhook.go | 165 ++++++++++++---------- 3 files changed, 88 insertions(+), 468 deletions(-) delete mode 100644 contentful_webhook.go delete mode 100644 contentful_webhook_test.go diff --git a/contentful_webhook.go b/contentful_webhook.go deleted file mode 100644 index cd3add2..0000000 --- a/contentful_webhook.go +++ /dev/null @@ -1,249 +0,0 @@ -package main - -import ( - "errors" - "fmt" - "strconv" - - "github.com/levigross/grequests" -) - -type spaceEntitySys struct { - Sys struct { - Type string `json:"type"` - ID string `json:"id"` - Version int `json:"version"` - Space link `json:"space"` - CreatedAt string `json:"createdAt"` - CreatedBy link `json:"createdBy"` - UpdatedAt string `json:"updatedAt"` - UpdatedBy link `json:"updatedBy"` - } `json:"sys"` -} - -type headerKeyValue struct { - Key string `json:"key"` - Value string `json:"value"` -} - -type webhookProperties struct { - Name string `json:"name"` - URL string `json:"url"` - Topics []string `json:"topics"` - HTTPBasicUsername string `json:"httpBasicUsername"` - // According to the CMA docs the stuff below shouldn't exist when GETing a webhook - // TODO check - HTTPBasicPassword string `json:"httpBasicPassword"` - Headers []headerKeyValue `json:"headers"` -} - -type webhookData struct { - spaceEntitySys - webhookProperties -} - -type webhookCollection struct { - collectionProperties - Items []webhookData `json:"items"` -} - -// func (wh *webhook) update(properties webhookProperties) error { -// updatedWh, err := updateWebhook( -// wh.client.cmaToken, -// wh.Sys.Space.Sys.ID, -// wh.Sys.Version, -// properties, -// ) -// if err != nil { -// return err -// } -// wh.Sys = updatedWh.Sys -// } - -func webhookPath(baseURL, spaceID, webhookID string) string { - return fmt.Sprintf("%s/spaces/%s/webhook_definitions/%s", baseURL, spaceID, webhookID) -} - -func createWebhook( - cmaToken string, - spaceID string, - webhookProps webhookProperties, -) (*webhookData, error) { - - path := webhookPath(baseURL, spaceID, "") - authHeader := fmt.Sprintf("Bearer %s", cmaToken) - - resp, err := grequests.Post(path, &grequests.RequestOptions{ - Headers: map[string]string{ - "Authorization": authHeader, - "Content-Type": "application/vnd.contentful.management.v1+json", - }, - JSON: webhookProps, - }) - - if err != nil { - return nil, err - } - - if resp.StatusCode == 401 { - return nil, errorUnauthorized - } - - if resp.StatusCode == 404 { - return nil, errorSpaceNotFound - } - - if resp.StatusCode != 201 { - return nil, errors.New(resp.String()) - } - - var wh webhookData - if err := resp.JSON(&wh); err != nil { - return nil, err - } - - return &wh, nil -} - -func updateWebhook( - cmaToken string, - spaceID string, - webhookID string, - version int, - webhookProps webhookProperties, -) (*webhookData, error) { - - path := webhookPath(baseURL, spaceID, webhookID) - authHeader := fmt.Sprintf("Bearer %s", cmaToken) - - resp, err := grequests.Put(path, &grequests.RequestOptions{ - Headers: map[string]string{ - "Authorization": authHeader, - "Content-Type": "application/vnd.contentful.management.v1+json", - "X-Contentful-Version": strconv.Itoa(version), - }, - JSON: webhookProps, - }) - - if err != nil { - return nil, err - } - - if resp.StatusCode == 401 { - return nil, errorUnauthorized - } - - if resp.StatusCode == 404 { - return nil, errorSpaceNotFound - } - - if resp.StatusCode != 200 { - return nil, errors.New(resp.String()) - } - - var wh webhookData - if err := resp.JSON(&wh); err != nil { - return nil, err - } - - return &wh, nil -} - -func readWebhook(cmaToken, spaceID, webhookID string) (*webhookData, error) { - path := webhookPath(baseURL, spaceID, webhookID) - authHeader := fmt.Sprintf("Bearer %s", cmaToken) - - res, err := grequests.Get(path, &grequests.RequestOptions{ - Headers: map[string]string{ - "Authorization": authHeader, - }, - }) - - if err != nil { - return nil, err - } - - if res.StatusCode == 401 { - return nil, errorUnauthorized - } - - // ...Sigh... The routing returns 503 if a space cannot be found, not 404. - // It's either abiding by the broken status code, or using the /token endpoint, which - // is more accurate but annoying. TODO: Check the /token endpoint - if res.StatusCode == 503 { - return nil, errorSpaceNotFound - } - - if res.StatusCode == 404 { - return nil, errorWebhookNotFound - } - - if res.StatusCode != 200 { - return nil, errors.New(res.String()) - } - - wh := &webhookData{} - if err := res.JSON(wh); err != nil { - return nil, err - } - - return wh, nil -} - -func deleteWebhook(cmaToken, spaceID, webhookID string) error { - path := webhookPath(baseURL, spaceID, webhookID) - authHeader := fmt.Sprintf("Bearer %s", cmaToken) - - resp, err := grequests.Delete(path, &grequests.RequestOptions{ - Headers: map[string]string{ - "Authorization": authHeader, - }, - }) - - if err != nil { - return err - } - - if resp.StatusCode == 401 { - return errorUnauthorized - } - - if resp.StatusCode == 404 { - return errorSpaceNotFound - } - - if resp.StatusCode != 204 { - msg := fmt.Sprintf("Error: unknown status code: %d", resp.StatusCode) - return errors.New(msg) - } - - return nil -} - -func listWebhooks(cmaToken, spaceID string) ([]webhookData, error) { - URL := webhookPath(baseURL, spaceID, "") - - resp, err := grequests.Get(URL, &grequests.RequestOptions{ - Headers: map[string]string{ - "Authorization": "Bearer " + cmaToken, - }, - }) - if err != nil { - return nil, err - } - - if resp.StatusCode == 401 { - return nil, errorUnauthorized - } - - if resp.StatusCode != 200 { - return nil, errors.New(resp.String()) - } - - webhookCol := &webhookCollection{} - if err := resp.JSON(webhookCol); err != nil { - return nil, err - } - - return webhookCol.Items, nil -} diff --git a/contentful_webhook_test.go b/contentful_webhook_test.go deleted file mode 100644 index 98783c0..0000000 --- a/contentful_webhook_test.go +++ /dev/null @@ -1,142 +0,0 @@ -package main - -import ( - "encoding/json" - "net/http" - "net/http/httptest" - "strconv" - - "github.com/stretchr/testify/assert" - - "testing" -) - -type testHandler struct { - handleFunc func(rw http.ResponseWriter, req *http.Request) -} - -func (h *testHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) { - h.handleFunc(rw, req) - defer req.Body.Close() -} - -func createExampleWebhook() webhookData { - return webhookData{ - spaceEntitySys{}, - webhookProperties{ - Name: "test-name", - URL: "http://test", - Topics: []string{"Entry.publish"}, - HTTPBasicUsername: "test-username", - HTTPBasicPassword: "test-password", - Headers: []headerKeyValue{ - headerKeyValue{ - Key: "test-key", - Value: "test-value", - }, - }, - }, - } -} - -func TestCreateWebhook(t *testing.T) { - cmaToken := "test-token" - spaceID := "test-space" - - whProps := createExampleWebhook().webhookProperties - - serveFn := func(w http.ResponseWriter, req *http.Request) { - assert.Equal(t, req.Method, "POST") - assert.Equal(t, req.RequestURI, "/spaces/"+spaceID+"/webhook_definitions/") - assert.Equal(t, "Bearer "+cmaToken, req.Header.Get("Authorization")) - assert.Equal(t, "application/vnd.contentful.management.v1+json", req.Header.Get("Content-Type")) - w.WriteHeader(201) - - var requestWh webhookData - assert.Nil(t, json.NewDecoder(req.Body).Decode(&requestWh)) - assert.Equal(t, whProps, requestWh.webhookProperties) - - err := json.NewEncoder(w).Encode(&webhookData{}) - assert.Nil(t, err) - } - - server := httptest.NewServer(&testHandler{handleFunc: serveFn}) - defer server.Close() - baseURL = server.URL - _, err := createWebhook(cmaToken, spaceID, whProps) - assert.Nil(t, err) -} - -func TestUpdateWebhook(t *testing.T) { - cmaToken := "test-token" - spaceID := "test-space" - webhookID := "test-webhook" - version := 1 - - whProps := createExampleWebhook().webhookProperties - - serveFn := func(w http.ResponseWriter, req *http.Request) { - assert.Equal(t, req.Method, "PUT") - assert.Equal(t, req.RequestURI, "/spaces/"+spaceID+"/webhook_definitions/"+webhookID) - assert.Equal(t, "Bearer "+cmaToken, req.Header.Get("Authorization")) - assert.Equal(t, "application/vnd.contentful.management.v1+json", req.Header.Get("Content-Type")) - assert.Equal(t, strconv.Itoa(version), req.Header.Get("X-Contentful-Version")) - w.WriteHeader(200) - - var requestWh webhookData - assert.Nil(t, json.NewDecoder(req.Body).Decode(&requestWh)) - assert.Equal(t, whProps, requestWh.webhookProperties) - - err := json.NewEncoder(w).Encode(&webhookData{}) - assert.Nil(t, err) - } - - server := httptest.NewServer(&testHandler{handleFunc: serveFn}) - defer server.Close() - baseURL = server.URL - _, err := updateWebhook(cmaToken, spaceID, webhookID, version, whProps) - assert.Nil(t, err) -} - -func TestReadWebhook(t *testing.T) { - cmaToken := "test-token" - spaceID := "test-space" - webhookID := "test-webhook" - - wh := createExampleWebhook() - - serveFn := func(w http.ResponseWriter, req *http.Request) { - assert.Equal(t, req.Method, "GET") - assert.Equal(t, req.RequestURI, "/spaces/"+spaceID+"/webhook_definitions/"+webhookID) - assert.Equal(t, "Bearer "+cmaToken, req.Header.Get("Authorization")) - - err := json.NewEncoder(w).Encode(&wh) - assert.Nil(t, err) - } - - server := httptest.NewServer(&testHandler{handleFunc: serveFn}) - defer server.Close() - baseURL = server.URL - _, err := readWebhook(cmaToken, spaceID, webhookID) - assert.Nil(t, err) -} - -func TestDeleteWebhook(t *testing.T) { - cmaToken := "test-token" - spaceID := "test-space" - webhookID := "test-webhook" - - serveFn := func(w http.ResponseWriter, req *http.Request) { - assert.Equal(t, req.Method, "DELETE") - assert.Equal(t, req.RequestURI, "/spaces/"+spaceID+"/webhook_definitions/"+webhookID) - assert.Equal(t, "Bearer "+cmaToken, req.Header.Get("Authorization")) - - w.WriteHeader(204) - } - - server := httptest.NewServer(&testHandler{handleFunc: serveFn}) - defer server.Close() - baseURL = server.URL - err := deleteWebhook(cmaToken, spaceID, webhookID) - assert.Nil(t, err) -} diff --git a/resource_contentful_webhook.go b/resource_contentful_webhook.go index 8fe12ec..f8ec11a 100644 --- a/resource_contentful_webhook.go +++ b/resource_contentful_webhook.go @@ -2,6 +2,7 @@ package main import ( "github.com/hashicorp/terraform/helper/schema" + contentful "github.com/tolgaakyuz/contentful.go" ) func resourceContentfulWebhook() *schema.Resource { @@ -59,165 +60,175 @@ func resourceContentfulWebhook() *schema.Resource { } } -func resourceCreateWebhook(d *schema.ResourceData, m interface{}) error { - configMap := m.(map[string]string) - cmaToken := configMap["cma_token"] - spaceID := d.Get("space_id").(string) +func resourceCreateWebhook(d *schema.ResourceData, m interface{}) (err error) { + configMap := m.(map[string]interface{}) + client := configMap["client"].(*contentful.Contentful) - headers := transformHeadersToContentfulFormat(d.Get("headers")) - topics := transformTopicsToContentfulFormat(d.Get("topics")) - - webhookprops := webhookProperties{ - Name: d.Get("name").(string), - URL: d.Get("url").(string), - Topics: topics, - Headers: headers, - HTTPBasicUsername: d.Get("http_basic_auth_username").(string), - HTTPBasicPassword: d.Get("http_basic_auth_password").(string), + space, err := client.GetSpace(d.Get("space_id").(string)) + if err != nil { + return err } - webhookjson, err := createWebhook( - cmaToken, - spaceID, - webhookprops, - ) + webhook := space.NewWebhook() + webhook.Name = d.Get("name").(string) + webhook.URL = d.Get("url").(string) + webhook.Topics = d.Get("topics").([]string) + webhook.Headers = transformHeadersToContentfulFormat(d.Get("headers")) + webhook.HTTPBasicUsername = d.Get("http_basic_auth_username").(string) + webhook.HTTPBasicPassword = d.Get("http_basic_auth_password").(string) + + err = webhook.Save() if err != nil { return err } - err = setWebhookProperties(d, webhookjson) + err = setWebhookProperties(d, webhook) if err != nil { return err } - d.SetId(webhookjson.Sys.ID) + d.SetId(webhook.Sys.ID) + return nil } -func resourceUpdateWebhook(d *schema.ResourceData, m interface{}) error { - configMap := m.(map[string]string) - cmaToken := configMap["cma_token"] - spaceID := d.Get("space_id").(string) - webhookID := d.Id() - version := d.Get("version").(int) +func resourceUpdateWebhook(d *schema.ResourceData, m interface{}) (err error) { + configMap := m.(map[string]interface{}) + client := configMap["client"].(*contentful.Contentful) - headers := transformHeadersToContentfulFormat(d.Get("headers")) - topics := transformTopicsToContentfulFormat(d.Get("topics")) + space, err := client.GetSpace(d.Get("space_id").(string)) + if err != nil { + return err + } - webhookprops := webhookProperties{ - Name: d.Get("name").(string), - URL: d.Get("url").(string), - Topics: topics, - Headers: headers, - HTTPBasicUsername: d.Get("http_basic_auth_username").(string), - HTTPBasicPassword: d.Get("http_basic_auth_password").(string), + webhook, err := space.GetWebhook(d.Id()) + if err != nil { + return err } - wh, err := updateWebhook(cmaToken, spaceID, webhookID, version, webhookprops) + webhook.Name = d.Get("name").(string) + webhook.URL = d.Get("url").(string) + webhook.Topics = d.Get("topics").([]string) + webhook.Headers = transformHeadersToContentfulFormat(d.Get("headers")) + webhook.HTTPBasicUsername = d.Get("http_basic_auth_username").(string) + webhook.HTTPBasicPassword = d.Get("http_basic_auth_password").(string) + + err = webhook.Save() if err != nil { return err } - err = setWebhookProperties(d, wh) + err = setWebhookProperties(d, webhook) if err != nil { return err } - d.SetId(wh.Sys.ID) + d.SetId(webhook.Sys.ID) + return nil } func resourceReadWebhook(d *schema.ResourceData, m interface{}) error { - configMap := m.(map[string]string) - cmaToken := configMap["cma_token"] - spaceID := d.Get("space_id").(string) - webhookID := d.Id() - wh, err := readWebhook(cmaToken, spaceID, webhookID) + configMap := m.(map[string]interface{}) + client := configMap["client"].(*contentful.Contentful) + + space, err := client.GetSpace(d.Get("space_id").(string)) + if err != nil { + return err + } - if err == errorWebhookNotFound { + webhook, err := space.GetWebhook(d.Id()) + if _, ok := err.(contentful.NotFoundError); ok { d.SetId("") return nil } - return setWebhookProperties(d, wh) + if err != nil { + return err + } + + return setWebhookProperties(d, webhook) } -func resourceDeleteWebhook(d *schema.ResourceData, m interface{}) error { - configMap := m.(map[string]string) - cmaToken := configMap["cma_token"] - spaceID := d.Get("space_id").(string) - webhookID := d.Id() +func resourceDeleteWebhook(d *schema.ResourceData, m interface{}) (err error) { + configMap := m.(map[string]interface{}) + client := configMap["client"].(*contentful.Contentful) - err := deleteWebhook(cmaToken, spaceID, webhookID) + space, err := client.GetSpace(d.Get("space_id").(string)) + if err != nil { + return err + } - if err == errorSpaceNotFound { + webhook, err := space.GetWebhook(d.Id()) + if err != nil { + return err + } + + err = webhook.Delete() + if _, ok := err.(contentful.NotFoundError); ok { return nil } return err } -func setWebhookProperties(d *schema.ResourceData, webhookjson *webhookData) error { +func setWebhookProperties(d *schema.ResourceData, webhook *contentful.Webhook) (err error) { headers := make(map[string]string) - for _, entry := range webhookjson.Headers { + for _, entry := range webhook.Headers { headers[entry.Key] = entry.Value } - err := d.Set("headers", headers) + + err = d.Set("headers", headers) if err != nil { return err } - err = d.Set("space_id", webhookjson.Sys.Space.Sys.ID) + err = d.Set("space_id", webhook.Sys.Space.Sys.ID) if err != nil { return err } - err = d.Set("version", webhookjson.Sys.Version) + err = d.Set("version", webhook.Sys.Version) if err != nil { return err } - err = d.Set("name", webhookjson.Name) + err = d.Set("name", webhook.Name) if err != nil { return err } - err = d.Set("url", webhookjson.URL) + err = d.Set("url", webhook.URL) if err != nil { return err } - err = d.Set("http_basic_auth_username", webhookjson.HTTPBasicUsername) + err = d.Set("http_basic_auth_username", webhook.HTTPBasicUsername) if err != nil { return err } - err = d.Set("http_basic_auth_password", webhookjson.HTTPBasicPassword) + err = d.Set("http_basic_auth_password", webhook.HTTPBasicPassword) if err != nil { return err } - err = d.Set("topics", webhookjson.Topics) + err = d.Set("topics", webhook.Topics) if err != nil { return err } return nil } -func transformHeadersToContentfulFormat(headersTerraform interface{}) []headerKeyValue { - headers := headersTerraform.(map[string]interface{}) - headerList := []headerKeyValue{} - for k, v := range headers { - val := v.(string) - headerList = append(headerList, headerKeyValue{Key: k, Value: val}) - } - return headerList -} +func transformHeadersToContentfulFormat(headersTerraform interface{}) []*contentful.WebhookHeader { + headers := []*contentful.WebhookHeader{} -func transformTopicsToContentfulFormat(topicsTerraform interface{}) []string { - topicList := []string{} - for _, v := range topicsTerraform.([]interface{}) { - topicList = append(topicList, v.(string)) + for k, v := range headersTerraform.(map[string]string) { + headers = append(headers, &contentful.WebhookHeader{ + Key: k, + Value: v, + }) } - return topicList + + return headers } From d0c9909f1e60375c1a55d53383d8acad8c2af9a5 Mon Sep 17 00:00:00 2001 From: Tolga Akyuz Date: Tue, 14 Mar 2017 15:58:41 +0100 Subject: [PATCH 006/192] delete models --- contentful_space.go | 38 -------------------------------------- 1 file changed, 38 deletions(-) delete mode 100644 contentful_space.go diff --git a/contentful_space.go b/contentful_space.go deleted file mode 100644 index 58d3e99..0000000 --- a/contentful_space.go +++ /dev/null @@ -1,38 +0,0 @@ -package main - -type collectionProperties struct { - Total int `json:"total"` - Limit int `json:"limit"` - Skip int `json:"skip"` - Sys struct { - Type string `json:"type"` - } `json:"sys"` -} - -type link struct { - Sys struct { - Type string `json:"type"` - LinkType string `json:"linkType"` - ID string `json:"id"` - } `json:"sys"` -} - -type spaceSys struct { - Type string `json:"type"` - ID string `json:"id"` - Version int `json:"version"` - CreatedAt string `json:"createdAt"` - UpdatedAt string `json:"updatedAt"` - CreatedBy link `json:"createdBy"` - UpdatedBy link `json:"updatedBy"` -} - -type spaceData struct { - Sys spaceSys `json:"sys"` - Name string `json:"name"` -} - -type spaceCollection struct { - collectionProperties - Items []spaceData `json:"items"` -} From 0902576f15721b18f9dd6f39b0daf604061b692a Mon Sep 17 00:00:00 2001 From: Tolga Akyuz Date: Tue, 14 Mar 2017 17:58:16 +0100 Subject: [PATCH 007/192] Space update test --- resource_contentful_space_test.go | 34 ++++++++++++++++--------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/resource_contentful_space_test.go b/resource_contentful_space_test.go index 4838c4a..686efa1 100644 --- a/resource_contentful_space_test.go +++ b/resource_contentful_space_test.go @@ -15,10 +15,15 @@ func TestAccContentfulSpace_Basic(t *testing.T) { Providers: testAccProviders, CheckDestroy: testAccCheckContentfulSpaceDestroy, Steps: []resource.TestStep{ - { - Config: testAccCheckContentfulSpaceConfig, + resource.TestStep{ + Config: testAccContentfulSpaceConfig, Check: resource.TestCheckResourceAttr( - "contentful_space.myspace", "name", "terraform test"), + "contentful_space.myspace", "name", "space-name"), + }, + resource.TestStep{ + Config: testAccContentfulSpaceUpdateConfig, + Check: resource.TestCheckResourceAttr( + "contentful_space.myspace", "name", "changed-space-name"), }, }, }) @@ -26,33 +31,30 @@ func TestAccContentfulSpace_Basic(t *testing.T) { func testAccCheckContentfulSpaceDestroy(s *terraform.State) error { configMap := testAccProvider.Meta().(map[string]interface{}) + client := configMap["client"].(*contentful.Contentful) for _, rs := range s.RootModule().Resources { if rs.Type != "contentful_space" { continue } - client := configMap["client"].(*contentful.Contentful) - _, err := client.GetSpace(rs.Primary.ID) + space, err := client.GetSpace(rs.Primary.ID) if err == nil { - return fmt.Errorf("Space %s still exists after destroy", rs.Primary.ID) - } - - switch t := err.(type) { - case contentful.NotFoundError: - return nil - default: - _ = t - return fmt.Errorf("Error checking space %s: %s", rs.Primary.ID, err) + return fmt.Errorf("Space %s still exists after destroy", space.ID()) } } return nil } -var testAccCheckContentfulSpaceConfig = ` +var testAccContentfulSpaceConfig = ` resource "contentful_space" "myspace" { - name = "terraform test" + name = "space-name" } +` +var testAccContentfulSpaceUpdateConfig = ` +resource "contentful_space" "myspace" { + name = "changed-space-name" +} ` From 5deec27c3f39de52797c45005220a9d478fbfba8 Mon Sep 17 00:00:00 2001 From: Luis Neves Date: Wed, 15 Mar 2017 11:57:24 +0100 Subject: [PATCH 008/192] Content type resource --- provider.go | 12 +- resource_contentful_contenttype.go | 202 +++++++++++++++++++++++++++++ 2 files changed, 210 insertions(+), 4 deletions(-) create mode 100644 resource_contentful_contenttype.go diff --git a/provider.go b/provider.go index b3a3e05..9083ab9 100644 --- a/provider.go +++ b/provider.go @@ -24,10 +24,11 @@ func Provider() terraform.ResourceProvider { }, }, ResourcesMap: map[string]*schema.Resource{ - "contentful_space": resourceContentfulSpace(), - "contentful_apikey": resourceContentfulAPIKey(), - "contentful_webhook": resourceContentfulWebhook(), - "contentful_locale": resourceContentfulLocale(), + "contentful_space": resourceContentfulSpace(), + "contentful_contenttype": resourceContentfulContentType(), + "contentful_apikey": resourceContentfulAPIKey(), + "contentful_webhook": resourceContentfulWebhook(), + "contentful_locale": resourceContentfulLocale(), }, ConfigureFunc: providerConfigure, } @@ -36,11 +37,14 @@ func Provider() terraform.ResourceProvider { func providerConfigure(d *schema.ResourceData) (interface{}, error) { c, err := contentful.New(&contentful.Settings{ CMAToken: d.Get("cma_token").(string), + BaseURL: "https://api.contentful.com", }) if err != nil { return nil, err } + c.Debug = true + config := map[string]interface{}{ "cma_token": d.Get("cma_token").(string), "organization_id": d.Get("organization_id").(string), diff --git a/resource_contentful_contenttype.go b/resource_contentful_contenttype.go new file mode 100644 index 0000000..a400292 --- /dev/null +++ b/resource_contentful_contenttype.go @@ -0,0 +1,202 @@ +package main + +import ( + "github.com/hashicorp/terraform/helper/schema" + contentful "github.com/tolgaakyuz/contentful.go" +) + +func resourceContentfulContentType() *schema.Resource { + return &schema.Resource{ + Create: resourceContentTypeCreate, + Read: resourceContentTypeRead, + Update: resourceContentTypeUpdate, + Delete: resourceContentTypeDelete, + + Schema: map[string]*schema.Schema{ + "space_id": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "id": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + "version": &schema.Schema{ + Type: schema.TypeInt, + Computed: true, + }, + "name": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + "description": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + "displayField": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + "field": &schema.Schema{ + Type: schema.TypeSet, + Required: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + "name": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + //@TODO Add ValidateFunc to validate field type + "type": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + "required": &schema.Schema{ + Type: schema.TypeBool, + Optional: true, + Default: true, + }, + // "localized": &schema.Schema{ + // Type: schema.TypeBool, + // Optional: true, + // Default: false, + // }, + "disabled": &schema.Schema{ + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + }, + }, + }, + }, + } +} + +func resourceContentTypeCreate(d *schema.ResourceData, m interface{}) (err error) { + configMap := m.(map[string]interface{}) + + client := configMap["client"].(*contentful.Contentful) + space, err := client.GetSpace(d.Get("space_id").(string)) + if err != nil { + return err + } + + ct := space.NewContentType() + ct.Name = d.Get("name").(string) + ct.DisplayField = d.Get("displayField").(string) + ct.Description = d.Get("description").(string) + + for _, field := range d.Get("field").(*schema.Set).List() { + ct.Fields = append(ct.Fields, &contentful.Field{ + ID: field.(map[string]interface{})["id"].(string), + Name: field.(map[string]interface{})["name"].(string), + Type: field.(map[string]interface{})["type"].(string), + // Localized: field.(map[string]interface{})["localized"].(bool), + Required: field.(map[string]interface{})["required"].(bool), + Disabled: field.(map[string]interface{})["disabled"].(bool), + }) + } + + if err = ct.Save(); err != nil { + return err + } + + if err = ct.Activate(); err != nil { + //@TODO Maybe delete the CT ? + return err + } + + if err = d.Set("version", ct.Sys.Version); err != nil { + return err + } + + d.SetId(ct.Sys.ID) + + return nil +} + +func resourceContentTypeRead(d *schema.ResourceData, m interface{}) (err error) { + configMap := m.(map[string]interface{}) + + client := configMap["client"].(*contentful.Contentful) + space, err := client.GetSpace(d.Get("space_id").(string)) + if err != nil { + return err + } + + _, err = space.GetContentType(d.Id()) + + return err +} + +func resourceContentTypeUpdate(d *schema.ResourceData, m interface{}) (err error) { + configMap := m.(map[string]interface{}) + + client := configMap["client"].(*contentful.Contentful) + space, err := client.GetSpace(d.Get("space_id").(string)) + if err != nil { + return err + } + + ct, err := space.GetContentType(d.Id()) + if err != nil { + return err + } + + ct.Name = d.Get("name").(string) + ct.DisplayField = d.Get("displayField").(string) + ct.Description = d.Get("description").(string) + + for _, field := range d.Get("field").(*schema.Set).List() { + ct.Fields = append(ct.Fields, &contentful.Field{ + ID: field.(map[string]interface{})["id"].(string), + Name: field.(map[string]interface{})["name"].(string), + Type: field.(map[string]interface{})["type"].(string), + // Localized: field.(map[string]interface{})["localized"].(bool), + Required: field.(map[string]interface{})["required"].(bool), + Disabled: field.(map[string]interface{})["disabled"].(bool), + }) + } + + if err = ct.Save(); err != nil { + return err + } + + if err = ct.Activate(); err != nil { + //@TODO Maybe delete the CT ? + return err + } + + if err = d.Set("version", ct.Sys.Version); err != nil { + return err + } + + return nil +} + +func resourceContentTypeDelete(d *schema.ResourceData, m interface{}) (err error) { + configMap := m.(map[string]interface{}) + + client := configMap["client"].(*contentful.Contentful) + space, err := client.GetSpace(d.Get("space_id").(string)) + if err != nil { + return err + } + + ct, err := space.GetContentType(d.Id()) + if err != nil { + return err + } + + if err = ct.Delete(); err != nil { + return err + } + + return nil +} From b06f4cea9dbbf8f676285cf6e69397947dbed10c Mon Sep 17 00:00:00 2001 From: Dani Hodovic Date: Wed, 15 Mar 2017 14:18:16 +0100 Subject: [PATCH 009/192] Add Dockerfile for testing --- Dockerfile-test | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 Dockerfile-test diff --git a/Dockerfile-test b/Dockerfile-test new file mode 100644 index 0000000..fe7d30c --- /dev/null +++ b/Dockerfile-test @@ -0,0 +1,9 @@ +FROM golang:1.8 + +WORKDIR /go/src/github.com/danihodovic/contentful-terraform + +COPY . /go/src/github.com/danihodovic/contentful-terraform + +RUN go get + +CMD go test From 7a1d7383a4014b112668ed3f86a238ab4ef3a41d Mon Sep 17 00:00:00 2001 From: Dani Hodovic Date: Wed, 15 Mar 2017 14:18:27 +0100 Subject: [PATCH 010/192] Add Makefile for building/testing Docker image --- Makefile | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 Makefile diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..abb81bc --- /dev/null +++ b/Makefile @@ -0,0 +1,11 @@ +.PHONY: build +build: + docker build -t contentful-terraform-test -f Dockerfile-test . + +.PHONY: test +test: build + docker run contentful-terraform-test go test + +.PHONY: interactive +interactive: + docker run -it -v $(shell pwd):/go/src/github.com/danihodovic/contentful-terraform contentful-terraform-test bash From 8476d0e202c433da26a438da5769388c960dea7e Mon Sep 17 00:00:00 2001 From: Dani Hodovic Date: Wed, 15 Mar 2017 14:18:45 +0100 Subject: [PATCH 011/192] Add circle.yml --- circle.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 circle.yml diff --git a/circle.yml b/circle.yml new file mode 100644 index 0000000..63f6940 --- /dev/null +++ b/circle.yml @@ -0,0 +1,11 @@ +machine: + pre: + # Install docker 1.10.0, can be removed when circle ships it + # https://discuss.circleci.com/t/docker-1-10-0-is-available-beta/2100 + - curl -sSL https://s3.amazonaws.com/circle-downloads/install-circleci-docker.sh | bash -s -- 1.10.0 + services: + - docker + +test: + override: + - make test From 9ee9585216e9fa407c8e44076278cf6a32d1ddb3 Mon Sep 17 00:00:00 2001 From: Dani Hodovic Date: Wed, 15 Mar 2017 14:23:35 +0100 Subject: [PATCH 012/192] Override dependencies to workaround CI We're using Docker as our base testing environment. Circle CI is trying to infer our project to a go project and build the dependencies. We need to override the dependency stage to ensure Circle CI does not infer anything. --- circle.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/circle.yml b/circle.yml index 63f6940..42e9248 100644 --- a/circle.yml +++ b/circle.yml @@ -6,6 +6,10 @@ machine: services: - docker +dependencies: + override: + - make build + test: override: - make test From 7bb27c047d5e8944aa817710fc3b373394f81b89 Mon Sep 17 00:00:00 2001 From: Tolga Akyuz Date: Wed, 15 Mar 2017 14:45:03 +0100 Subject: [PATCH 013/192] webhook resource test case --- provider.go | 3 + resource_contentful_space.go | 1 - resource_contentful_webhook.go | 18 ++- resource_contentful_webhook_test.go | 190 ++++++++++++++++++++++++++++ 4 files changed, 207 insertions(+), 5 deletions(-) create mode 100644 resource_contentful_webhook_test.go diff --git a/provider.go b/provider.go index b3a3e05..6471175 100644 --- a/provider.go +++ b/provider.go @@ -36,11 +36,14 @@ func Provider() terraform.ResourceProvider { func providerConfigure(d *schema.ResourceData) (interface{}, error) { c, err := contentful.New(&contentful.Settings{ CMAToken: d.Get("cma_token").(string), + BaseURL: "https://api.flinkly.com", }) if err != nil { return nil, err } + // c.Debug = true + config := map[string]interface{}{ "cma_token": d.Get("cma_token").(string), "organization_id": d.Get("organization_id").(string), diff --git a/resource_contentful_space.go b/resource_contentful_space.go index 0f9ebce..f6f9bb0 100644 --- a/resource_contentful_space.go +++ b/resource_contentful_space.go @@ -81,7 +81,6 @@ func resourceSpaceUpdate(d *schema.ResourceData, m interface{}) (err error) { } space.Name = d.Get("name").(string) - // space.Sys.Version = d.Get("version").(int) err = space.Save() if err != nil { return err diff --git a/resource_contentful_webhook.go b/resource_contentful_webhook.go index f8ec11a..c3b56fa 100644 --- a/resource_contentful_webhook.go +++ b/resource_contentful_webhook.go @@ -72,7 +72,7 @@ func resourceCreateWebhook(d *schema.ResourceData, m interface{}) (err error) { webhook := space.NewWebhook() webhook.Name = d.Get("name").(string) webhook.URL = d.Get("url").(string) - webhook.Topics = d.Get("topics").([]string) + webhook.Topics = transformTopicsToContentfulFormat(d.Get("topics").([]interface{})) webhook.Headers = transformHeadersToContentfulFormat(d.Get("headers")) webhook.HTTPBasicUsername = d.Get("http_basic_auth_username").(string) webhook.HTTPBasicPassword = d.Get("http_basic_auth_password").(string) @@ -108,7 +108,7 @@ func resourceUpdateWebhook(d *schema.ResourceData, m interface{}) (err error) { webhook.Name = d.Get("name").(string) webhook.URL = d.Get("url").(string) - webhook.Topics = d.Get("topics").([]string) + webhook.Topics = transformTopicsToContentfulFormat(d.Get("topics").([]interface{})) webhook.Headers = transformHeadersToContentfulFormat(d.Get("headers")) webhook.HTTPBasicUsername = d.Get("http_basic_auth_username").(string) webhook.HTTPBasicPassword = d.Get("http_basic_auth_password").(string) @@ -223,12 +223,22 @@ func setWebhookProperties(d *schema.ResourceData, webhook *contentful.Webhook) ( func transformHeadersToContentfulFormat(headersTerraform interface{}) []*contentful.WebhookHeader { headers := []*contentful.WebhookHeader{} - for k, v := range headersTerraform.(map[string]string) { + for k, v := range headersTerraform.(map[string]interface{}) { headers = append(headers, &contentful.WebhookHeader{ Key: k, - Value: v, + Value: v.(string), }) } return headers } + +func transformTopicsToContentfulFormat(topicsTerraform []interface{}) []string { + var topics []string + + for _, v := range topicsTerraform { + topics = append(topics, v.(string)) + } + + return topics +} diff --git a/resource_contentful_webhook_test.go b/resource_contentful_webhook_test.go new file mode 100644 index 0000000..3ecc6b0 --- /dev/null +++ b/resource_contentful_webhook_test.go @@ -0,0 +1,190 @@ +package main + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + contentful "github.com/tolgaakyuz/contentful.go" +) + +func TestAccContentfulWebhook_Basic(t *testing.T) { + var webhook contentful.Webhook + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccContentfulWebhookDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccContentfulWebhookConfig, + Check: resource.ComposeTestCheckFunc( + testAccCheckContentfulWebhookExists("contentful_webhook.mywebhook", &webhook), + testAccCheckContentfulWebhookAttributes(&webhook, map[string]interface{}{ + "name": "webhook-name", + "url": "https://www.example.com/test", + "http_basic_auth_username": "username", + }), + ), + }, + resource.TestStep{ + Config: testAccContentfulWebhookUpdateConfig, + Check: resource.ComposeTestCheckFunc( + testAccCheckContentfulWebhookExists("contentful_webhook.mywebhook", &webhook), + testAccCheckContentfulWebhookAttributes(&webhook, map[string]interface{}{ + "name": "webhook-name-updated", + "url": "https://www.example.com/test-updated", + "http_basic_auth_username": "username-updated", + }), + ), + }, + }, + }) +} + +func testAccCheckContentfulWebhookExists(n string, webhook *contentful.Webhook) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not Found: %s", n) + } + + // get space id from resource data + spaceID := rs.Primary.Attributes["space_id"] + if spaceID == "" { + return fmt.Errorf("No space_id is set") + } + + // check webhook resource id + if rs.Primary.ID == "" { + return fmt.Errorf("No webhook ID is set") + } + + // read config map and get sdk client + configMap := testAccProvider.Meta().(map[string]interface{}) + client := configMap["client"].(*contentful.Contentful) + + space, err := client.GetSpace(spaceID) + if err != nil { + return fmt.Errorf("No space with this id: %s", spaceID) + } + + contentfulWebhook, err := space.GetWebhook(rs.Primary.ID) + if err != nil { + return err + } + + *webhook = *contentfulWebhook + + return nil + } +} + +func testAccCheckContentfulWebhookAttributes(webhook *contentful.Webhook, attrs map[string]interface{}) resource.TestCheckFunc { + return func(s *terraform.State) error { + name := attrs["name"].(string) + if webhook.Name != name { + return fmt.Errorf("Webhook name does not match: %s, %s", webhook.Name, name) + } + + url := attrs["url"].(string) + if webhook.URL != url { + return fmt.Errorf("Webhook url does not match: %s, %s", webhook.URL, url) + } + + /* topics := attrs["topics"].([]string) + + headers := attrs["headers"].(map[string]string) */ + + httpBasicAuthUsername := attrs["http_basic_auth_username"].(string) + if webhook.HTTPBasicUsername != httpBasicAuthUsername { + return fmt.Errorf("Webhook http_basic_auth_username does not match: %s, %s", webhook.HTTPBasicUsername, httpBasicAuthUsername) + } + + return nil + } +} + +func testAccContentfulWebhookDestroy(s *terraform.State) error { + + for _, rs := range s.RootModule().Resources { + if rs.Type != "contentful_webhook" { + continue + } + + // get space id from resource data + spaceID := rs.Primary.Attributes["space_id"] + if spaceID == "" { + return fmt.Errorf("No space_id is set") + } + + // check webhook resource id + if rs.Primary.ID == "" { + return fmt.Errorf("No webhook ID is set") + } + + // read config map and get sdk client + configMap := testAccProvider.Meta().(map[string]interface{}) + client := configMap["client"].(*contentful.Contentful) + + space, err := client.GetSpace(spaceID) + if err != nil { + return fmt.Errorf("No space with this id: %s", spaceID) + } + + _, err = space.GetWebhook(rs.Primary.ID) + if _, ok := err.(contentful.NotFoundError); ok { + return nil + } + + return fmt.Errorf("Webhook still exists with id: %s", rs.Primary.ID) + } + + return nil +} + +var testAccContentfulWebhookConfig = ` +resource "contentful_space" "myspace" { + name = "space-name" +} + +resource "contentful_webhook" "mywebhook" { + space_id = "${contentful_space.myspace.id}" + depends_on = ["contentful_space.myspace"] + + name = "webhook-name" + url= "https://www.example.com/test" + topics = [ + "Entry.create", + "ContentType.create", + ] + headers { + header1 = "header1-value" + header2 = "header2-value" + } + http_basic_auth_username = "username" + http_basic_auth_password = "password" +} +` + +var testAccContentfulWebhookUpdateConfig = ` +resource "contentful_space" "myspace" { + name = "space-name" +} + +resource "contentful_webhook" "mywebhook" { + depends_on = ["contentful_space.myspace"] + space_id = "${contentful_space.myspace.id}" + + name = "webhook-name-updated" + url= "https://www.example.com/test-updated" + topics = ["topic1", "topic2", "topic3"] + headers = { + header1 = "header1-value-updated" + header2 = "header2-value-updated" + } + http_basic_auth_username = "username-updated" + http_basic_auth_password = "password-updated" +} +` From b1e54a5bf680ae322c84e55e44b90afd8e1452fd Mon Sep 17 00:00:00 2001 From: Luis Neves Date: Thu, 16 Mar 2017 17:22:04 +0100 Subject: [PATCH 014/192] Content types first tests --- resource_contentful_contenttype.go | 3 +- resource_contentful_contenttype_test.go | 160 ++++++++++++++++++++++++ 2 files changed, 162 insertions(+), 1 deletion(-) create mode 100644 resource_contentful_contenttype_test.go diff --git a/resource_contentful_contenttype.go b/resource_contentful_contenttype.go index a400292..f6cf9d7 100644 --- a/resource_contentful_contenttype.go +++ b/resource_contentful_contenttype.go @@ -41,6 +41,7 @@ func resourceContentfulContentType() *schema.Resource { "field": &schema.Schema{ Type: schema.TypeSet, Required: true, + MinItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "id": &schema.Schema{ @@ -80,8 +81,8 @@ func resourceContentfulContentType() *schema.Resource { func resourceContentTypeCreate(d *schema.ResourceData, m interface{}) (err error) { configMap := m.(map[string]interface{}) - client := configMap["client"].(*contentful.Contentful) + space, err := client.GetSpace(d.Get("space_id").(string)) if err != nil { return err diff --git a/resource_contentful_contenttype_test.go b/resource_contentful_contenttype_test.go new file mode 100644 index 0000000..b766eda --- /dev/null +++ b/resource_contentful_contenttype_test.go @@ -0,0 +1,160 @@ +package main + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + contentful "github.com/tolgaakyuz/contentful.go" +) + +func TestAccContentfulContentType_Basic(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckContentfulContentTypeDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccContentfulContentTypeConfig, + Check: resource.TestCheckResourceAttr( + "contentful_contenttype.mycontenttype", "name", "Terraform"), + }, + resource.TestStep{ + Config: testAccContentfulContentTypeUpdateConfig, + Check: resource.TestCheckResourceAttr( + "contentful_space.myspace", "name", "changed-space-name"), + }, + }, + }) +} + +func testAccCheckContentfulContentTypeExists(n string, contentType *contentful.ContentType) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found %s", n) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No content type ID is set") + } + + spaceID := rs.Primary.Attributes["space_id"] + if spaceID == "" { + return fmt.Errorf("No space_id is set") + } + + configMap := testAccProvider.Meta().(map[string]interface{}) + client := configMap["client"].(*contentful.Contentful) + + space, err := client.GetSpace(spaceID) + if err != nil { + return fmt.Errorf("No space with this id: %s", rs.Primary.Attributes["space_id"]) + } + + ct, err := space.GetContentType(rs.Primary.ID) + if err != nil { + return err + } + + *contentType = *ct + + return nil + } +} + +func testAccCheckContentfulContentTypeDestroy(s *terraform.State) (err error) { + + for _, rs := range s.RootModule().Resources { + if rs.Type != "contentful_contenttype" { + continue + } + + spaceID := rs.Primary.Attributes["space_id"] + if spaceID == "" { + return fmt.Errorf("No space_id is set") + } + + configMap := testAccProvider.Meta().(map[string]interface{}) + client := configMap["client"].(*contentful.Contentful) + + space, err := client.GetSpace(spaceID) + + if err != nil { + if _, ok := err.(contentful.NotFoundError); ok { + return nil + } + return fmt.Errorf("Error checking space_id: %s", spaceID) + } + + _, err = space.GetContentType(rs.Primary.ID) + if _, ok := err.(contentful.NotFoundError); ok { + return nil + } + + return fmt.Errorf("Content Type still exists with id: %s", rs.Primary.ID) + } + + return nil +} + +var testAccContentfulContentTypeConfig = ` +resource "contentful_space" "myspace" { + name = "Terraform Space" +} + +resource "contentful_contenttype" "mycontenttype" { + space_id = "${contentful_space.myspace.id}" + depends_on = ["contentful_space.myspace"] + + name = "Terraform" + description = "Terraform Content Type" + displayField = "field1" + + field { + id = "field1" + name = "Field 1" + type = "Text" + required = true + } + + field { + id = "field2" + name = "Field 2" + type = "Number" + required = false + } + +} +` + +var testAccContentfulContentTypeUpdateConfig = ` +resource "contentful_space" "myspace" { + name = "Terraform Space" +} + +resource "contentful_contenttype" "mycontenttype" { + space_id = "${contentful_space.myspace.id}" + depends_on = ["contentful_space.myspace"] + + name = "Terraform name change" + description = "Terraform Content Type" + displayField = "field1" + + field { + id = "field1" + name = "Field 1" + type = "Text" + required = true + } + + field { + id = "field2" + name = "Field 2" + type = "Number" + required = false + } + +} +` From a3696f3596de0135be4e01f88b5313b0291c8f89 Mon Sep 17 00:00:00 2001 From: Tolga Akyuz Date: Fri, 17 Mar 2017 08:01:38 +0300 Subject: [PATCH 015/192] webhook fixture configuration fix --- resource_contentful_webhook.go | 6 +----- resource_contentful_webhook_test.go | 6 +++++- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/resource_contentful_webhook.go b/resource_contentful_webhook.go index c3b56fa..5c3e638 100644 --- a/resource_contentful_webhook.go +++ b/resource_contentful_webhook.go @@ -208,15 +208,11 @@ func setWebhookProperties(d *schema.ResourceData, webhook *contentful.Webhook) ( return err } - err = d.Set("http_basic_auth_password", webhook.HTTPBasicPassword) - if err != nil { - return err - } - err = d.Set("topics", webhook.Topics) if err != nil { return err } + return nil } diff --git a/resource_contentful_webhook_test.go b/resource_contentful_webhook_test.go index 3ecc6b0..a7af96d 100644 --- a/resource_contentful_webhook_test.go +++ b/resource_contentful_webhook_test.go @@ -179,7 +179,11 @@ resource "contentful_webhook" "mywebhook" { name = "webhook-name-updated" url= "https://www.example.com/test-updated" - topics = ["topic1", "topic2", "topic3"] + topics = [ + "Entry.create", + "ContentType.create", + "Asset.*", + ] headers = { header1 = "header1-value-updated" header2 = "header2-value-updated" From f46a44207950a8c32adfcfe56cf0494d36fef73c Mon Sep 17 00:00:00 2001 From: Tolga Akyuz Date: Fri, 17 Mar 2017 08:03:13 +0300 Subject: [PATCH 016/192] Delete unused content_type files --- contentful_content_type.go | 1 - contentful_content_type_test.go | 1 - 2 files changed, 2 deletions(-) delete mode 100644 contentful_content_type.go delete mode 100644 contentful_content_type_test.go diff --git a/contentful_content_type.go b/contentful_content_type.go deleted file mode 100644 index 06ab7d0..0000000 --- a/contentful_content_type.go +++ /dev/null @@ -1 +0,0 @@ -package main diff --git a/contentful_content_type_test.go b/contentful_content_type_test.go deleted file mode 100644 index 06ab7d0..0000000 --- a/contentful_content_type_test.go +++ /dev/null @@ -1 +0,0 @@ -package main From d48b0f8f32d6712c0c133f63c195df0a7d59787c Mon Sep 17 00:00:00 2001 From: Tolga Akyuz Date: Fri, 17 Mar 2017 08:19:55 +0300 Subject: [PATCH 017/192] Run SDK in debug mode when TF_LOG env is presented --- provider.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/provider.go b/provider.go index ed787b9..a519b5d 100644 --- a/provider.go +++ b/provider.go @@ -1,6 +1,8 @@ package main import ( + "os" + "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/terraform" contentful "github.com/tolgaakyuz/contentful.go" @@ -43,7 +45,9 @@ func providerConfigure(d *schema.ResourceData) (interface{}, error) { return nil, err } - // c.Debug = true + if os.Getenv("TF_LOG") != "" { + c.Debug = true + } config := map[string]interface{}{ "cma_token": d.Get("cma_token").(string), From 177e5689a092a2345f1a4a2966bf52b6db9474c0 Mon Sep 17 00:00:00 2001 From: Tolga Akyuz Date: Fri, 17 Mar 2017 10:10:13 +0300 Subject: [PATCH 018/192] Webhook destroy check fix --- resource_contentful_space.go | 1 - resource_contentful_webhook_test.go | 6 ++++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/resource_contentful_space.go b/resource_contentful_space.go index f6f9bb0..ef4182e 100644 --- a/resource_contentful_space.go +++ b/resource_contentful_space.go @@ -99,7 +99,6 @@ func resourceSpaceDelete(d *schema.ResourceData, m interface{}) (err error) { } err = space.Delete() - if _, ok := err.(contentful.NotFoundError); ok { return nil } diff --git a/resource_contentful_webhook_test.go b/resource_contentful_webhook_test.go index a7af96d..e3a5f11 100644 --- a/resource_contentful_webhook_test.go +++ b/resource_contentful_webhook_test.go @@ -107,7 +107,6 @@ func testAccCheckContentfulWebhookAttributes(webhook *contentful.Webhook, attrs } func testAccContentfulWebhookDestroy(s *terraform.State) error { - for _, rs := range s.RootModule().Resources { if rs.Type != "contentful_webhook" { continue @@ -129,8 +128,11 @@ func testAccContentfulWebhookDestroy(s *terraform.State) error { client := configMap["client"].(*contentful.Contentful) space, err := client.GetSpace(spaceID) + if _, ok := err.(contentful.NotFoundError); ok { + return nil + } if err != nil { - return fmt.Errorf("No space with this id: %s", spaceID) + return err } _, err = space.GetWebhook(rs.Primary.ID) From 22e90486c702a7b58db9b33bcb4b7c28c5eb6327 Mon Sep 17 00:00:00 2001 From: Luis Neves Date: Fri, 17 Mar 2017 10:11:42 +0100 Subject: [PATCH 019/192] CT update and tests ok --- resource_contentful_contenttype.go | 31 +++++++++++++++++++++++-- resource_contentful_contenttype_test.go | 8 ++++++- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/resource_contentful_contenttype.go b/resource_contentful_contenttype.go index f6cf9d7..ed291bf 100644 --- a/resource_contentful_contenttype.go +++ b/resource_contentful_contenttype.go @@ -154,8 +154,9 @@ func resourceContentTypeUpdate(d *schema.ResourceData, m interface{}) (err error ct.DisplayField = d.Get("displayField").(string) ct.Description = d.Get("description").(string) + var fields []*contentful.Field for _, field := range d.Get("field").(*schema.Set).List() { - ct.Fields = append(ct.Fields, &contentful.Field{ + fields = append(fields, &contentful.Field{ ID: field.(map[string]interface{})["id"].(string), Name: field.(map[string]interface{})["name"].(string), Type: field.(map[string]interface{})["type"].(string), @@ -165,6 +166,8 @@ func resourceContentTypeUpdate(d *schema.ResourceData, m interface{}) (err error }) } + ct.Fields = fields + if err = ct.Save(); err != nil { return err } @@ -174,7 +177,7 @@ func resourceContentTypeUpdate(d *schema.ResourceData, m interface{}) (err error return err } - if err = d.Set("version", ct.Sys.Version); err != nil { + if err = setContentTypeProperties(d, ct); err != nil { return err } @@ -201,3 +204,27 @@ func resourceContentTypeDelete(d *schema.ResourceData, m interface{}) (err error return nil } + +func setContentTypeProperties(d *schema.ResourceData, ct *contentful.ContentType) (err error) { + if err = d.Set("space_id", ct.Sys.Space.ID()); err != nil { + return err + } + + if err = d.Set("version", ct.Sys.Version); err != nil { + return err + } + + if err = d.Set("name", ct.Name); err != nil { + return err + } + + if err = d.Set("description", ct.Description); err != nil { + return err + } + + if err = d.Set("displayField", ct.DisplayField); err != nil { + return err + } + + return nil +} diff --git a/resource_contentful_contenttype_test.go b/resource_contentful_contenttype_test.go index b766eda..45ddf8a 100644 --- a/resource_contentful_contenttype_test.go +++ b/resource_contentful_contenttype_test.go @@ -23,7 +23,7 @@ func TestAccContentfulContentType_Basic(t *testing.T) { resource.TestStep{ Config: testAccContentfulContentTypeUpdateConfig, Check: resource.TestCheckResourceAttr( - "contentful_space.myspace", "name", "changed-space-name"), + "contentful_contenttype.mycontenttype", "name", "Terraform name change"), }, }, }) @@ -156,5 +156,11 @@ resource "contentful_contenttype" "mycontenttype" { required = false } + field { + id = "field3" + name = "Field 3" + type = "Text" + required = true + } } ` From 5deb8528dd3a7113472534a90764a57572032649 Mon Sep 17 00:00:00 2001 From: Luis Neves Date: Fri, 17 Mar 2017 14:01:32 +0100 Subject: [PATCH 020/192] changes to content type --- resource_contentful_contenttype.go | 63 +++++++++++------------------- 1 file changed, 22 insertions(+), 41 deletions(-) diff --git a/resource_contentful_contenttype.go b/resource_contentful_contenttype.go index ed291bf..966bba1 100644 --- a/resource_contentful_contenttype.go +++ b/resource_contentful_contenttype.go @@ -34,7 +34,7 @@ func resourceContentfulContentType() *schema.Resource { Type: schema.TypeString, Optional: true, }, - "displayField": &schema.Schema{ + "display_field": &schema.Schema{ Type: schema.TypeString, Required: true, }, @@ -62,11 +62,11 @@ func resourceContentfulContentType() *schema.Resource { Optional: true, Default: true, }, - // "localized": &schema.Schema{ - // Type: schema.TypeBool, - // Optional: true, - // Default: false, - // }, + "localized": &schema.Schema{ + Type: schema.TypeBool, + Optional: true, + Default: false, + }, "disabled": &schema.Schema{ Type: schema.TypeBool, Optional: true, @@ -90,17 +90,17 @@ func resourceContentTypeCreate(d *schema.ResourceData, m interface{}) (err error ct := space.NewContentType() ct.Name = d.Get("name").(string) - ct.DisplayField = d.Get("displayField").(string) + ct.DisplayField = d.Get("display_field").(string) ct.Description = d.Get("description").(string) for _, field := range d.Get("field").(*schema.Set).List() { ct.Fields = append(ct.Fields, &contentful.Field{ - ID: field.(map[string]interface{})["id"].(string), - Name: field.(map[string]interface{})["name"].(string), - Type: field.(map[string]interface{})["type"].(string), - // Localized: field.(map[string]interface{})["localized"].(bool), - Required: field.(map[string]interface{})["required"].(bool), - Disabled: field.(map[string]interface{})["disabled"].(bool), + ID: field.(map[string]interface{})["id"].(string), + Name: field.(map[string]interface{})["name"].(string), + Type: field.(map[string]interface{})["type"].(string), + Localized: field.(map[string]interface{})["localized"].(bool), + Required: field.(map[string]interface{})["required"].(bool), + Disabled: field.(map[string]interface{})["disabled"].(bool), }) } @@ -113,7 +113,7 @@ func resourceContentTypeCreate(d *schema.ResourceData, m interface{}) (err error return err } - if err = d.Set("version", ct.Sys.Version); err != nil { + if err = setContentTypeProperties(d, ct); err != nil { return err } @@ -151,18 +151,18 @@ func resourceContentTypeUpdate(d *schema.ResourceData, m interface{}) (err error } ct.Name = d.Get("name").(string) - ct.DisplayField = d.Get("displayField").(string) + ct.DisplayField = d.Get("display_field").(string) ct.Description = d.Get("description").(string) var fields []*contentful.Field for _, field := range d.Get("field").(*schema.Set).List() { fields = append(fields, &contentful.Field{ - ID: field.(map[string]interface{})["id"].(string), - Name: field.(map[string]interface{})["name"].(string), - Type: field.(map[string]interface{})["type"].(string), - // Localized: field.(map[string]interface{})["localized"].(bool), - Required: field.(map[string]interface{})["required"].(bool), - Disabled: field.(map[string]interface{})["disabled"].(bool), + ID: field.(map[string]interface{})["id"].(string), + Name: field.(map[string]interface{})["name"].(string), + Type: field.(map[string]interface{})["type"].(string), + Localized: field.(map[string]interface{})["localized"].(bool), + Required: field.(map[string]interface{})["required"].(bool), + Disabled: field.(map[string]interface{})["disabled"].(bool), }) } @@ -177,11 +177,7 @@ func resourceContentTypeUpdate(d *schema.ResourceData, m interface{}) (err error return err } - if err = setContentTypeProperties(d, ct); err != nil { - return err - } - - return nil + return setContentTypeProperties(d, ct) } func resourceContentTypeDelete(d *schema.ResourceData, m interface{}) (err error) { @@ -206,25 +202,10 @@ func resourceContentTypeDelete(d *schema.ResourceData, m interface{}) (err error } func setContentTypeProperties(d *schema.ResourceData, ct *contentful.ContentType) (err error) { - if err = d.Set("space_id", ct.Sys.Space.ID()); err != nil { - return err - } if err = d.Set("version", ct.Sys.Version); err != nil { return err } - if err = d.Set("name", ct.Name); err != nil { - return err - } - - if err = d.Set("description", ct.Description); err != nil { - return err - } - - if err = d.Set("displayField", ct.DisplayField); err != nil { - return err - } - return nil } From ed4a8d64d7bc4f6d760e986e3436a06eb74df4f3 Mon Sep 17 00:00:00 2001 From: Dani Hodovic Date: Fri, 17 Mar 2017 14:12:02 +0100 Subject: [PATCH 021/192] Run tests in verbose mode C & P from the terraform test source code: // Tests will fail unless the verbose flag (`go test -v`, or explicitly // the "-test.v" flag) is set. Because some acceptance tests take quite // long, we require the verbose flag so users are able to see progress // output. The tests don't seem to fail, however it's not visible that the terraform tests are skipped when -v is not used. --- Dockerfile-test | 2 +- Makefile | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/Dockerfile-test b/Dockerfile-test index fe7d30c..4fb4cad 100644 --- a/Dockerfile-test +++ b/Dockerfile-test @@ -6,4 +6,4 @@ COPY . /go/src/github.com/danihodovic/contentful-terraform RUN go get -CMD go test +CMD go test -v diff --git a/Makefile b/Makefile index abb81bc..efd6453 100644 --- a/Makefile +++ b/Makefile @@ -4,8 +4,13 @@ build: .PHONY: test test: build - docker run contentful-terraform-test go test + docker run \ + contentful-terraform-test \ + go test -v .PHONY: interactive interactive: - docker run -it -v $(shell pwd):/go/src/github.com/danihodovic/contentful-terraform contentful-terraform-test bash + docker run -it \ + -v $(shell pwd):/go/src/github.com/danihodovic/contentful-terraform \ + contentful-terraform-test \ + bash From fb88f68ccde089b116342da9efaa3cba43530b12 Mon Sep 17 00:00:00 2001 From: Tolga Akyuz Date: Mon, 20 Mar 2017 10:48:22 +0300 Subject: [PATCH 022/192] [Changed] Sdk package name --- provider.go | 2 +- resource_contentful_apikey.go | 2 +- resource_contentful_contenttype.go | 2 +- resource_contentful_contenttype_test.go | 2 +- resource_contentful_locale.go | 2 +- resource_contentful_space.go | 2 +- resource_contentful_space_test.go | 2 +- resource_contentful_webhook.go | 2 +- resource_contentful_webhook_test.go | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/provider.go b/provider.go index a519b5d..8eef1a0 100644 --- a/provider.go +++ b/provider.go @@ -5,7 +5,7 @@ import ( "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/terraform" - contentful "github.com/tolgaakyuz/contentful.go" + contentful "github.com/tolgaakyuz/contentful-go" ) // Provider does shit diff --git a/resource_contentful_apikey.go b/resource_contentful_apikey.go index 62c2443..ece4aea 100644 --- a/resource_contentful_apikey.go +++ b/resource_contentful_apikey.go @@ -2,7 +2,7 @@ package main import ( "github.com/hashicorp/terraform/helper/schema" - contentful "github.com/tolgaakyuz/contentful.go" + contentful "github.com/tolgaakyuz/contentful-go" ) func resourceContentfulAPIKey() *schema.Resource { diff --git a/resource_contentful_contenttype.go b/resource_contentful_contenttype.go index ed291bf..61f6a3a 100644 --- a/resource_contentful_contenttype.go +++ b/resource_contentful_contenttype.go @@ -2,7 +2,7 @@ package main import ( "github.com/hashicorp/terraform/helper/schema" - contentful "github.com/tolgaakyuz/contentful.go" + contentful "github.com/tolgaakyuz/contentful-go" ) func resourceContentfulContentType() *schema.Resource { diff --git a/resource_contentful_contenttype_test.go b/resource_contentful_contenttype_test.go index 45ddf8a..81782ac 100644 --- a/resource_contentful_contenttype_test.go +++ b/resource_contentful_contenttype_test.go @@ -6,7 +6,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" - contentful "github.com/tolgaakyuz/contentful.go" + contentful "github.com/tolgaakyuz/contentful-go" ) func TestAccContentfulContentType_Basic(t *testing.T) { diff --git a/resource_contentful_locale.go b/resource_contentful_locale.go index 056b4d6..6afeec9 100644 --- a/resource_contentful_locale.go +++ b/resource_contentful_locale.go @@ -2,7 +2,7 @@ package main import ( "github.com/hashicorp/terraform/helper/schema" - contentful "github.com/tolgaakyuz/contentful.go" + contentful "github.com/tolgaakyuz/contentful-go" ) func resourceContentfulLocale() *schema.Resource { diff --git a/resource_contentful_space.go b/resource_contentful_space.go index ef4182e..decbdcf 100644 --- a/resource_contentful_space.go +++ b/resource_contentful_space.go @@ -2,7 +2,7 @@ package main import ( "github.com/hashicorp/terraform/helper/schema" - contentful "github.com/tolgaakyuz/contentful.go" + contentful "github.com/tolgaakyuz/contentful-go" ) func resourceContentfulSpace() *schema.Resource { diff --git a/resource_contentful_space_test.go b/resource_contentful_space_test.go index 686efa1..a39e40f 100644 --- a/resource_contentful_space_test.go +++ b/resource_contentful_space_test.go @@ -6,7 +6,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" - contentful "github.com/tolgaakyuz/contentful.go" + contentful "github.com/tolgaakyuz/contentful-go" ) func TestAccContentfulSpace_Basic(t *testing.T) { diff --git a/resource_contentful_webhook.go b/resource_contentful_webhook.go index 5c3e638..5bc01df 100644 --- a/resource_contentful_webhook.go +++ b/resource_contentful_webhook.go @@ -2,7 +2,7 @@ package main import ( "github.com/hashicorp/terraform/helper/schema" - contentful "github.com/tolgaakyuz/contentful.go" + contentful "github.com/tolgaakyuz/contentful-go" ) func resourceContentfulWebhook() *schema.Resource { diff --git a/resource_contentful_webhook_test.go b/resource_contentful_webhook_test.go index e3a5f11..52f1869 100644 --- a/resource_contentful_webhook_test.go +++ b/resource_contentful_webhook_test.go @@ -6,7 +6,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" - contentful "github.com/tolgaakyuz/contentful.go" + contentful "github.com/tolgaakyuz/contentful-go" ) func TestAccContentfulWebhook_Basic(t *testing.T) { From 21794ab503869fd5df0d13c9608be33c2fc4ee4b Mon Sep 17 00:00:00 2001 From: Tolga Akyuz Date: Mon, 20 Mar 2017 15:34:34 +0300 Subject: [PATCH 023/192] use new sdk usage, only store sdk client in provider config --- provider.go | 19 ++++--------------- resource_contentful_apikey.go | 12 ++++-------- resource_contentful_contenttype.go | 12 ++++-------- resource_contentful_contenttype_test.go | 12 ++++-------- resource_contentful_locale.go | 12 ++++-------- resource_contentful_space.go | 14 +++++--------- resource_contentful_space_test.go | 3 +-- resource_contentful_webhook.go | 12 ++++-------- resource_contentful_webhook_test.go | 10 ++++------ 9 files changed, 34 insertions(+), 72 deletions(-) diff --git a/provider.go b/provider.go index 8eef1a0..9e47ad8 100644 --- a/provider.go +++ b/provider.go @@ -37,23 +37,12 @@ func Provider() terraform.ResourceProvider { } func providerConfigure(d *schema.ResourceData) (interface{}, error) { - c, err := contentful.New(&contentful.Settings{ - CMAToken: d.Get("cma_token").(string), - BaseURL: "https://api.flinkly.com", - }) - if err != nil { - return nil, err - } + cma := contentful.NewCMA(d.Get("cma_token").(string)) + cma.SetOrganization(d.Get("organization_id").(string)) if os.Getenv("TF_LOG") != "" { - c.Debug = true - } - - config := map[string]interface{}{ - "cma_token": d.Get("cma_token").(string), - "organization_id": d.Get("organization_id").(string), - "client": c, + cma.Debug = true } - return config, nil + return cma, nil } diff --git a/resource_contentful_apikey.go b/resource_contentful_apikey.go index ece4aea..0037ace 100644 --- a/resource_contentful_apikey.go +++ b/resource_contentful_apikey.go @@ -43,8 +43,7 @@ func resourceContentfulAPIKey() *schema.Resource { } func resourceCreateAPIKey(d *schema.ResourceData, m interface{}) (err error) { - configMap := m.(map[string]interface{}) - client := configMap["client"].(*contentful.Contentful) + client := m.(*contentful.Contentful) space, err := client.GetSpace(d.Get("space_id").(string)) if err != nil { @@ -68,8 +67,7 @@ func resourceCreateAPIKey(d *schema.ResourceData, m interface{}) (err error) { } func resourceUpdateAPIKey(d *schema.ResourceData, m interface{}) (err error) { - configMap := m.(map[string]interface{}) - client := configMap["client"].(*contentful.Contentful) + client := m.(*contentful.Contentful) space, err := client.GetSpace(d.Get("space_id").(string)) if err != nil { @@ -97,8 +95,7 @@ func resourceUpdateAPIKey(d *schema.ResourceData, m interface{}) (err error) { } func resourceReadAPIKey(d *schema.ResourceData, m interface{}) (err error) { - configMap := m.(map[string]interface{}) - client := configMap["client"].(*contentful.Contentful) + client := m.(*contentful.Contentful) space, err := client.GetSpace(d.Get("space_id").(string)) if err != nil { @@ -115,8 +112,7 @@ func resourceReadAPIKey(d *schema.ResourceData, m interface{}) (err error) { } func resourceDeleteAPIKey(d *schema.ResourceData, m interface{}) (err error) { - configMap := m.(map[string]interface{}) - client := configMap["client"].(*contentful.Contentful) + client := m.(*contentful.Contentful) space, err := client.GetSpace(d.Get("space_id").(string)) if err != nil { diff --git a/resource_contentful_contenttype.go b/resource_contentful_contenttype.go index 6ed2bfa..aa6787b 100644 --- a/resource_contentful_contenttype.go +++ b/resource_contentful_contenttype.go @@ -80,8 +80,7 @@ func resourceContentfulContentType() *schema.Resource { } func resourceContentTypeCreate(d *schema.ResourceData, m interface{}) (err error) { - configMap := m.(map[string]interface{}) - client := configMap["client"].(*contentful.Contentful) + client := m.(*contentful.Contentful) space, err := client.GetSpace(d.Get("space_id").(string)) if err != nil { @@ -123,9 +122,8 @@ func resourceContentTypeCreate(d *schema.ResourceData, m interface{}) (err error } func resourceContentTypeRead(d *schema.ResourceData, m interface{}) (err error) { - configMap := m.(map[string]interface{}) + client := m.(*contentful.Contentful) - client := configMap["client"].(*contentful.Contentful) space, err := client.GetSpace(d.Get("space_id").(string)) if err != nil { return err @@ -137,9 +135,8 @@ func resourceContentTypeRead(d *schema.ResourceData, m interface{}) (err error) } func resourceContentTypeUpdate(d *schema.ResourceData, m interface{}) (err error) { - configMap := m.(map[string]interface{}) + client := m.(*contentful.Contentful) - client := configMap["client"].(*contentful.Contentful) space, err := client.GetSpace(d.Get("space_id").(string)) if err != nil { return err @@ -181,9 +178,8 @@ func resourceContentTypeUpdate(d *schema.ResourceData, m interface{}) (err error } func resourceContentTypeDelete(d *schema.ResourceData, m interface{}) (err error) { - configMap := m.(map[string]interface{}) + client := m.(*contentful.Contentful) - client := configMap["client"].(*contentful.Contentful) space, err := client.GetSpace(d.Get("space_id").(string)) if err != nil { return err diff --git a/resource_contentful_contenttype_test.go b/resource_contentful_contenttype_test.go index 81782ac..040c838 100644 --- a/resource_contentful_contenttype_test.go +++ b/resource_contentful_contenttype_test.go @@ -45,8 +45,7 @@ func testAccCheckContentfulContentTypeExists(n string, contentType *contentful.C return fmt.Errorf("No space_id is set") } - configMap := testAccProvider.Meta().(map[string]interface{}) - client := configMap["client"].(*contentful.Contentful) + client := testAccProvider.Meta().(*contentful.Contentful) space, err := client.GetSpace(spaceID) if err != nil { @@ -65,7 +64,6 @@ func testAccCheckContentfulContentTypeExists(n string, contentType *contentful.C } func testAccCheckContentfulContentTypeDestroy(s *terraform.State) (err error) { - for _, rs := range s.RootModule().Resources { if rs.Type != "contentful_contenttype" { continue @@ -76,8 +74,7 @@ func testAccCheckContentfulContentTypeDestroy(s *terraform.State) (err error) { return fmt.Errorf("No space_id is set") } - configMap := testAccProvider.Meta().(map[string]interface{}) - client := configMap["client"].(*contentful.Contentful) + client := testAccProvider.Meta().(*contentful.Contentful) space, err := client.GetSpace(spaceID) @@ -110,7 +107,7 @@ resource "contentful_contenttype" "mycontenttype" { name = "Terraform" description = "Terraform Content Type" - displayField = "field1" + display_field = "field1" field { id = "field1" @@ -125,7 +122,6 @@ resource "contentful_contenttype" "mycontenttype" { type = "Number" required = false } - } ` @@ -140,7 +136,7 @@ resource "contentful_contenttype" "mycontenttype" { name = "Terraform name change" description = "Terraform Content Type" - displayField = "field1" + display_field = "field1" field { id = "field1" diff --git a/resource_contentful_locale.go b/resource_contentful_locale.go index 6afeec9..97a041a 100644 --- a/resource_contentful_locale.go +++ b/resource_contentful_locale.go @@ -49,8 +49,7 @@ func resourceContentfulLocale() *schema.Resource { } func resourceCreateLocale(d *schema.ResourceData, m interface{}) (err error) { - configMap := m.(map[string]interface{}) - client := configMap["client"].(*contentful.Contentful) + client := m.(*contentful.Contentful) space, err := client.GetSpace(d.Get("space_id").(string)) if err != nil { @@ -79,8 +78,7 @@ func resourceCreateLocale(d *schema.ResourceData, m interface{}) (err error) { } func resourceReadLocale(d *schema.ResourceData, m interface{}) error { - configMap := m.(map[string]interface{}) - client := configMap["client"].(*contentful.Contentful) + client := m.(*contentful.Contentful) space, err := client.GetSpace(d.Get("space_id").(string)) if err != nil { @@ -101,8 +99,7 @@ func resourceReadLocale(d *schema.ResourceData, m interface{}) error { } func resourceUpdateLocale(d *schema.ResourceData, m interface{}) (err error) { - configMap := m.(map[string]interface{}) - client := configMap["client"].(*contentful.Contentful) + client := m.(*contentful.Contentful) space, err := client.GetSpace(d.Get("space_id").(string)) if err != nil { @@ -132,8 +129,7 @@ func resourceUpdateLocale(d *schema.ResourceData, m interface{}) (err error) { } func resourceDeleteLocale(d *schema.ResourceData, m interface{}) (err error) { - configMap := m.(map[string]interface{}) - client := configMap["client"].(*contentful.Contentful) + client := m.(*contentful.Contentful) space, err := client.GetSpace(d.Get("space_id").(string)) if err != nil { diff --git a/resource_contentful_space.go b/resource_contentful_space.go index decbdcf..4def47f 100644 --- a/resource_contentful_space.go +++ b/resource_contentful_space.go @@ -36,10 +36,9 @@ func resourceContentfulSpace() *schema.Resource { } func resourceSpaceCreate(d *schema.ResourceData, m interface{}) (err error) { - configMap := m.(map[string]interface{}) + client := m.(*contentful.Contentful) - client := configMap["client"].(*contentful.Contentful) - space := client.NewSpace(configMap["organization_id"].(string)) + space := client.NewSpace() space.Name = d.Get("name").(string) space.DefaultLocale = d.Get("default_locale").(string) err = space.Save() @@ -58,9 +57,8 @@ func resourceSpaceCreate(d *schema.ResourceData, m interface{}) (err error) { } func resourceSpaceRead(d *schema.ResourceData, m interface{}) error { - configMap := m.(map[string]interface{}) + client := m.(*contentful.Contentful) - client := configMap["client"].(*contentful.Contentful) _, err := client.GetSpace(d.Id()) if _, ok := err.(contentful.NotFoundError); ok { @@ -72,9 +70,8 @@ func resourceSpaceRead(d *schema.ResourceData, m interface{}) error { } func resourceSpaceUpdate(d *schema.ResourceData, m interface{}) (err error) { - configMap := m.(map[string]interface{}) + client := m.(*contentful.Contentful) - client := configMap["client"].(*contentful.Contentful) space, err := client.GetSpace(d.Id()) if err != nil { return err @@ -90,9 +87,8 @@ func resourceSpaceUpdate(d *schema.ResourceData, m interface{}) (err error) { } func resourceSpaceDelete(d *schema.ResourceData, m interface{}) (err error) { - configMap := m.(map[string]interface{}) + client := m.(*contentful.Contentful) - client := configMap["client"].(*contentful.Contentful) space, err := client.GetSpace(d.Id()) if err != nil { return err diff --git a/resource_contentful_space_test.go b/resource_contentful_space_test.go index a39e40f..cc5cf82 100644 --- a/resource_contentful_space_test.go +++ b/resource_contentful_space_test.go @@ -30,8 +30,7 @@ func TestAccContentfulSpace_Basic(t *testing.T) { } func testAccCheckContentfulSpaceDestroy(s *terraform.State) error { - configMap := testAccProvider.Meta().(map[string]interface{}) - client := configMap["client"].(*contentful.Contentful) + client := testAccProvider.Meta().(*contentful.Contentful) for _, rs := range s.RootModule().Resources { if rs.Type != "contentful_space" { diff --git a/resource_contentful_webhook.go b/resource_contentful_webhook.go index 5bc01df..db2f9cd 100644 --- a/resource_contentful_webhook.go +++ b/resource_contentful_webhook.go @@ -61,8 +61,7 @@ func resourceContentfulWebhook() *schema.Resource { } func resourceCreateWebhook(d *schema.ResourceData, m interface{}) (err error) { - configMap := m.(map[string]interface{}) - client := configMap["client"].(*contentful.Contentful) + client := m.(*contentful.Contentful) space, err := client.GetSpace(d.Get("space_id").(string)) if err != nil { @@ -93,8 +92,7 @@ func resourceCreateWebhook(d *schema.ResourceData, m interface{}) (err error) { } func resourceUpdateWebhook(d *schema.ResourceData, m interface{}) (err error) { - configMap := m.(map[string]interface{}) - client := configMap["client"].(*contentful.Contentful) + client := m.(*contentful.Contentful) space, err := client.GetSpace(d.Get("space_id").(string)) if err != nil { @@ -129,8 +127,7 @@ func resourceUpdateWebhook(d *schema.ResourceData, m interface{}) (err error) { } func resourceReadWebhook(d *schema.ResourceData, m interface{}) error { - configMap := m.(map[string]interface{}) - client := configMap["client"].(*contentful.Contentful) + client := m.(*contentful.Contentful) space, err := client.GetSpace(d.Get("space_id").(string)) if err != nil { @@ -151,8 +148,7 @@ func resourceReadWebhook(d *schema.ResourceData, m interface{}) error { } func resourceDeleteWebhook(d *schema.ResourceData, m interface{}) (err error) { - configMap := m.(map[string]interface{}) - client := configMap["client"].(*contentful.Contentful) + client := m.(*contentful.Contentful) space, err := client.GetSpace(d.Get("space_id").(string)) if err != nil { diff --git a/resource_contentful_webhook_test.go b/resource_contentful_webhook_test.go index 52f1869..21579bc 100644 --- a/resource_contentful_webhook_test.go +++ b/resource_contentful_webhook_test.go @@ -61,9 +61,8 @@ func testAccCheckContentfulWebhookExists(n string, webhook *contentful.Webhook) return fmt.Errorf("No webhook ID is set") } - // read config map and get sdk client - configMap := testAccProvider.Meta().(map[string]interface{}) - client := configMap["client"].(*contentful.Contentful) + // sdk client + client := testAccProvider.Meta().(*contentful.Contentful) space, err := client.GetSpace(spaceID) if err != nil { @@ -123,9 +122,8 @@ func testAccContentfulWebhookDestroy(s *terraform.State) error { return fmt.Errorf("No webhook ID is set") } - // read config map and get sdk client - configMap := testAccProvider.Meta().(map[string]interface{}) - client := configMap["client"].(*contentful.Contentful) + // sdk client + client := testAccProvider.Meta().(*contentful.Contentful) space, err := client.GetSpace(spaceID) if _, ok := err.(contentful.NotFoundError); ok { From 0647cbd09739cee9c71896755c8dd8cf7180a4e0 Mon Sep 17 00:00:00 2001 From: Dani Hodovic Date: Mon, 20 Mar 2017 15:03:02 +0100 Subject: [PATCH 024/192] Add Makefile command for end-to-end tests Adds a Makefile command for running end-to-end tests using Contentful. Requires that the following environment variables are set: - CONTENTFUL_MANAGEMENT_TOKEN - CONTENTFUL_ORGANIZATION_ID --- Makefile | 19 +++++++++++++++++-- circle.yml | 2 +- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index efd6453..bce3756 100644 --- a/Makefile +++ b/Makefile @@ -2,15 +2,30 @@ build: docker build -t contentful-terraform-test -f Dockerfile-test . -.PHONY: test -test: build +.PHONY: test-unit +test-unit: build docker run \ contentful-terraform-test \ go test -v +# Runs an end-to-end integration test using Contentful. +# Requires that the following environment variables are set: +# - CONTENTFUL_MANAGEMENT_TOKEN +# - CONTENTFUL_ORGANIZATION_ID +.PHONY: test-integration +test-integration: build + docker run \ + -e CONTENTFUL_MANAGEMENT_TOKEN \ + -e CONTENTFUL_ORGANIZATION_ID \ + -e "TF_ACC=true" \ + contentful-terraform-test \ + go test -v + .PHONY: interactive interactive: docker run -it \ -v $(shell pwd):/go/src/github.com/danihodovic/contentful-terraform \ + -e CONTENTFUL_MANAGEMENT_TOKEN \ + -e CONTENTFUL_ORGANIZATION_ID \ contentful-terraform-test \ bash diff --git a/circle.yml b/circle.yml index 42e9248..1959fde 100644 --- a/circle.yml +++ b/circle.yml @@ -12,4 +12,4 @@ dependencies: test: override: - - make test + - make test-unit From bf9d4da618a3c5afcbeedf8d51b2382863fc6646 Mon Sep 17 00:00:00 2001 From: Dani Hodovic Date: Mon, 20 Mar 2017 15:04:25 +0100 Subject: [PATCH 025/192] Run end-to-end tests on Circle CI --- circle.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/circle.yml b/circle.yml index 1959fde..e6b22da 100644 --- a/circle.yml +++ b/circle.yml @@ -12,4 +12,4 @@ dependencies: test: override: - - make test-unit + - make test-integration From 8c01fb44805df2c28456159c1b7b4b160f628811 Mon Sep 17 00:00:00 2001 From: Dani Hodovic Date: Mon, 20 Mar 2017 15:05:59 +0100 Subject: [PATCH 026/192] Ignore .envrc Ignore .envrc as it's common to use direnv to set directory-local environment variables. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index b73f675..62b43e7 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ terraform-provider-contentful +.envrc From 9eeb645beec941b634a2dc2a169cdfca9fc0b351 Mon Sep 17 00:00:00 2001 From: Dani Hodovic Date: Mon, 20 Mar 2017 15:19:23 +0100 Subject: [PATCH 027/192] Don't run end-to-end tests on CI Contentful limits the amount of spaces you create in an hour. Each CI build will trigger a space creation and we'll run into failed builds more often. Let's revert back to unit tests on CI and manually test big changes. --- circle.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/circle.yml b/circle.yml index e6b22da..1959fde 100644 --- a/circle.yml +++ b/circle.yml @@ -12,4 +12,4 @@ dependencies: test: override: - - make test-integration + - make test-unit From 46622c7fc8953bfe05706295fbdc30c8ea5a3016 Mon Sep 17 00:00:00 2001 From: Dani Hodovic Date: Tue, 21 Mar 2017 10:56:39 +0100 Subject: [PATCH 028/192] Cache go get dependencies Running 'go get' after copying the source files causes us to re-build all dependencies on every source file change. If we instead specify our dependencies in install-dependencies.sh we can install and cache them before installing the source files. It's a ghetto approach, but greatly improves build times between tests. --- Dockerfile-test | 6 ++++-- install-dependencies.sh | 7 +++++++ 2 files changed, 11 insertions(+), 2 deletions(-) create mode 100755 install-dependencies.sh diff --git a/Dockerfile-test b/Dockerfile-test index 4fb4cad..12e7961 100644 --- a/Dockerfile-test +++ b/Dockerfile-test @@ -2,8 +2,10 @@ FROM golang:1.8 WORKDIR /go/src/github.com/danihodovic/contentful-terraform -COPY . /go/src/github.com/danihodovic/contentful-terraform +# http://stackoverflow.com/questions/39278756/cache-go-get-in-docker-build +COPY ./install-dependencies.sh /go/src/github.com/danihodovic/contentful-terraform/ +RUN ./install-dependencies.sh -RUN go get +COPY . /go/src/github.com/danihodovic/contentful-terraform CMD go test -v diff --git a/install-dependencies.sh b/install-dependencies.sh new file mode 100755 index 0000000..656d26a --- /dev/null +++ b/install-dependencies.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash +# Let's avoid rebuilding the dependencies each time a source file changes. +# See: http://stackoverflow.com/questions/39278756/cache-go-get-in-docker-build +go get github.com/hashicorp/terraform/terraform +go get github.com/hashicorp/terraform/helper/resource +go get github.com/hashicorp/terraform/helper/schema +go get github.com/tolgaakyuz/contentful-go From 60e9915d6c8cf3587ce03a94d7dae62c6da99f7b Mon Sep 17 00:00:00 2001 From: Luis Neves Date: Tue, 21 Mar 2017 16:00:09 +0100 Subject: [PATCH 029/192] Added MIT license --- LICENSE | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d8b47e8 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2017 Contentful + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. From 069efb52359404cadcc5bde1514be6868bf42c14 Mon Sep 17 00:00:00 2001 From: Luis Neves Date: Tue, 21 Mar 2017 16:12:22 +0100 Subject: [PATCH 030/192] Adjusted README --- README.md | 139 ++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 119 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index e35e173..6981627 100644 --- a/README.md +++ b/README.md @@ -1,44 +1,143 @@ -# Contentful Terraform Provider +[![Build Status](https://img.shields.io/circleci/project/github/danihodovic/contentful-terraform.svg?branch=master)](https://circleci.com/gh/danihodovic/contentful-terraform) +[![semantic-release](https://img.shields.io/github/release/danihodovic/contentful-terraform.svg)](https://github.com/semantic-release/semantic-release) +[![license](https://img.shields.io/github/license/danihodovic/contentful-terraform.svg)](https://github.com/danihodovic/contentful-terraform/blob/master/LICENSE) -# Overview -Supports: +Terraform Provider for [Contentful's](https://www.contentful.com) Content Management API + +# About + +[Contentful](https://www.contentful.com) is a content management platform for web applications, mobile apps and connected devices. It allows you to create, edit & manage content in the cloud and publish it anywhere via a powerful API. Contentful offers tools for managing editorial teams and enabling cooperation between organizations. + +[Terraform](https://www.terraform.io) is a tool for building, changing, and versioning infrastructure safely and efficiently. Terraform can manage existing and popular service providers as well as custom in-house solutions. + +# Features + +Create, update and delete Contentful resources such as: - [x] Spaces - [ ] Content Types - [x] API Keys - [x] Webhooks -- [ ] Locales (not tested) +- [ ] Locales -# TODO -- [ ] Add proper Terraform tests using `github.com/hashicorp/terraform/helper/resource`. - E.g https://github.com/hashicorp/terraform/blob/master/builtin/providers/bitbucket/resource_hook_test.go#L12-L45 -- [ ] Possibly serialize the JSON so that Terraform can notice the entire diff in read operations. - Current we only compare stored variables. -- [ ] Perhaps write a proper Go SDK for Contentful +# Getting started -# Testing -We have unit tests mocking the Contentful HTTP API using `net/http/httptest` which asserts that the -request headers/payloads we send are valid according to Contentful. +Download [terraform](https://www.terraform.io/downloads.html) for your platform. +Follow the [Installing Terraform](https://www.terraform.io/intro/getting-started/install.html) instructions. +Create a directory where your terraform files and states will be placed. Although not mandatory this should be placed under a version control software such as git. +Make sure you have your Content Management API Token and the organization ID before starting. As an alternative to configuring the provider in the terraform file you can also set environment variables. - go test +```sh + # For Linux/Mac OS + export CONTENTFUL_ORGANIZATION_ID= + export CONTENTFUL_MANAGEMENT_TOKEN= +``` -# Using the plugin +``` + REM For Windows + setx CONTENTFUL_ORGANIZATION_ID "" + setx CONTENTFUL_MANAGEMENT_TOKEN "" +``` + +# Using the provider Build the binary $ go build -o terraform-provider-contentful -Add it to your ~/.terraformrc +Add it to your ~/.terraformrc (or %APPDATA%/terraform.rc for Windows) $ cat ~/.terraformrc providers { - contentful = "/home/dani/repos/go_pkg/src/github.com/danihodovic/contentful-terraform/terraform-provider-contentful" + contentful = "/terraform-provider-contentful" } -Use the provider +Use the provider by creating a main.tf file with: provider "contentful" { - cma_token = "" - organization_id = "" + cma_token = "" + organization_id = "" } resource "contentful_space" "test" { name = "my-update-space-name" } + +Run the terraform plan + + terraform plan -out=contentful.plan + +Check the changes +``` +The refreshed state will be used to calculate this plan, but will not be +persisted to local or remote state storage. + +The Terraform execution plan has been generated and is shown below. +Resources are shown in alphabetical order for quick scanning. Green resources +will be created (or destroyed and then created if an existing resource +exists), yellow resources are being changed in-place, and red resources +will be destroyed. Cyan entries are data sources to be read. + +Your plan was also saved to the path below. Call the "apply" subcommand +with this plan file and Terraform will exactly execute this execution +plan. + +Path: contentful.plan + ++ contentful_space.test + default_locale: "en" + name: "my-update-space-name" + version: "" + + +Plan: 1 to add, 0 to change, 0 to destroy. +``` + +Apply the plan +``` +contentful_space.test: Creating... + default_locale: "" => "en" + name: "" => "my-update-space-name" + version: "" => "" +contentful_space.test: Creation complete (ID: yculypygam9h) + +Apply complete! Resources: 1 added, 0 changed, 0 destroyed. + +The state of your infrastructure has been saved to the path +below. This state is required to modify and destroy your +infrastructure, so keep it safe. To inspect the complete state +use the `terraform show` command. + +State path: +``` + +## Testing + + TF_ACC=1 go test -v + +To enable higher verbose mode + + TF_LOG=debug TF_ACC=1 go test -v + +## Documentation/References + +### Hashicorp +[Terraform plugins](https://www.terraform.io/docs/plugins/basics.html) + +[Writing custom terraform providers](https://www.hashicorp.com/blog/writing-custom-terraform-providers) + +### Other references +Julien Fabre: [Writing a Terraform provider](http://blog.jfabre.net/2017/01/22/writing-terraform-provider) + +## Versioning + +This project strictly follows [Semantic Versioning](http://semver.org/) by use of [semantic-release](https://github.com/semantic-release/semantic-release). + +This means that new versions are released automatically as fixes, features or breaking changes are released. + +You can check the changelog on the [releases](https://github.com/danihodovic/contentful-terraform/releases) page. + +## Support + +If you have a problem with this provider, please file an [issue](https://github.com/danihodovic/contentful-terraform/issues/new) here on Github. + +## License + +MIT From 09c481d9b39944d484c893b690532d330674f466 Mon Sep 17 00:00:00 2001 From: Luis Neves Date: Tue, 21 Mar 2017 16:37:17 +0100 Subject: [PATCH 031/192] Adjusted README a bit more --- README.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6981627..ccee823 100644 --- a/README.md +++ b/README.md @@ -21,9 +21,16 @@ Create, update and delete Contentful resources such as: # Getting started +Download [go](https://golang.org/dl) for your platform. + +Follow the [Install the Go tools](https://golang.org/doc/install#install) instructions. + Download [terraform](https://www.terraform.io/downloads.html) for your platform. + Follow the [Installing Terraform](https://www.terraform.io/intro/getting-started/install.html) instructions. -Create a directory where your terraform files and states will be placed. Although not mandatory this should be placed under a version control software such as git. + +Create a directory where your terraform files and states will be placed. Although not mandatory this should be placed under a version control software such as [git](https://git-scm.com). + Make sure you have your Content Management API Token and the organization ID before starting. As an alternative to configuring the provider in the terraform file you can also set environment variables. ```sh From 59917b1ca5dc52a7b4f8c65b5e7cc3369586c335 Mon Sep 17 00:00:00 2001 From: Luis Neves Date: Wed, 22 Mar 2017 10:42:35 +0100 Subject: [PATCH 032/192] Removed Versioning section from README as no versioning will be implemented --- README.md | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index ccee823..d611486 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ -[![Build Status](https://img.shields.io/circleci/project/github/danihodovic/contentful-terraform.svg?branch=master)](https://circleci.com/gh/danihodovic/contentful-terraform) -[![semantic-release](https://img.shields.io/github/release/danihodovic/contentful-terraform.svg)](https://github.com/semantic-release/semantic-release) -[![license](https://img.shields.io/github/license/danihodovic/contentful-terraform.svg)](https://github.com/danihodovic/contentful-terraform/blob/master/LICENSE) +[![Build Status](https://img.shields.io/circleci/project/github/contentful-labs/terraform-contentful.svg?branch=master)](https://circleci.com/gh/contentful-labs/terraform-contentful) +[![license](https://img.shields.io/github/license/contentful-labs/terraform-contentful.svg)](https://github.com/contentful-labs/terraform-contentful/blob/master/LICENSE) Terraform Provider for [Contentful's](https://www.contentful.com) Content Management API @@ -133,17 +132,9 @@ To enable higher verbose mode ### Other references Julien Fabre: [Writing a Terraform provider](http://blog.jfabre.net/2017/01/22/writing-terraform-provider) -## Versioning - -This project strictly follows [Semantic Versioning](http://semver.org/) by use of [semantic-release](https://github.com/semantic-release/semantic-release). - -This means that new versions are released automatically as fixes, features or breaking changes are released. - -You can check the changelog on the [releases](https://github.com/danihodovic/contentful-terraform/releases) page. - ## Support -If you have a problem with this provider, please file an [issue](https://github.com/danihodovic/contentful-terraform/issues/new) here on Github. +If you have a problem with this provider, please file an [issue](https://github.com/contentful-labs/terraform-contentful/issues/new) here on Github. ## License From c06f7a9df3a93c12eef7ed9be910ddc83605f483 Mon Sep 17 00:00:00 2001 From: Luis Neves Date: Wed, 29 Mar 2017 17:20:09 +0200 Subject: [PATCH 033/192] Resource contenttype (#12) * Fields can now be removed and changed * Added support for linked fields * Fix: items variable scope Creating `items` variable on higher scope was resulting in every `field` having same `items` * Added updates for linked CTs * use contentful-go@v0.1.0 * Renamed linkContentType validation to link_content_type. Added link_mimetype_group and size validations * [Added] field validations * Validations on item level are now List of String. Some tests adjustments --- resource_contentful_apikey.go | 34 +--- resource_contentful_contenttype.go | 252 +++++++++++++++++++----- resource_contentful_contenttype_test.go | 112 +++++++---- resource_contentful_locale.go | 46 ++--- resource_contentful_space.go | 25 ++- resource_contentful_space_test.go | 13 +- resource_contentful_webhook.go | 52 ++--- resource_contentful_webhook_test.go | 18 +- test.tf | 50 ----- 9 files changed, 344 insertions(+), 258 deletions(-) delete mode 100644 test.tf diff --git a/resource_contentful_apikey.go b/resource_contentful_apikey.go index 0037ace..8eddd60 100644 --- a/resource_contentful_apikey.go +++ b/resource_contentful_apikey.go @@ -45,14 +45,11 @@ func resourceContentfulAPIKey() *schema.Resource { func resourceCreateAPIKey(d *schema.ResourceData, m interface{}) (err error) { client := m.(*contentful.Contentful) - space, err := client.GetSpace(d.Get("space_id").(string)) - if err != nil { - return err + apiKey := &contentful.APIKey{ + Name: d.Get("name").(string), } - apiKey := space.NewAPIKey() - apiKey.Name = d.Get("name").(string) - err = apiKey.Save() + err = client.APIKeys.Upsert(d.Get("space_id").(string), apiKey) if err != nil { return err } @@ -69,18 +66,13 @@ func resourceCreateAPIKey(d *schema.ResourceData, m interface{}) (err error) { func resourceUpdateAPIKey(d *schema.ResourceData, m interface{}) (err error) { client := m.(*contentful.Contentful) - space, err := client.GetSpace(d.Get("space_id").(string)) - if err != nil { - return err - } - - apiKey, err := space.GetAPIKey(d.Id()) + apiKey, err := client.APIKeys.Get(d.Get("space_id").(string), d.Id()) if err != nil { return err } apiKey.Name = d.Get("name").(string) - err = apiKey.Save() + err = client.APIKeys.Upsert(d.Get("space_id").(string), apiKey) if err != nil { return err } @@ -97,12 +89,7 @@ func resourceUpdateAPIKey(d *schema.ResourceData, m interface{}) (err error) { func resourceReadAPIKey(d *schema.ResourceData, m interface{}) (err error) { client := m.(*contentful.Contentful) - space, err := client.GetSpace(d.Get("space_id").(string)) - if err != nil { - return err - } - - apiKey, err := space.GetAPIKey(d.Id()) + apiKey, err := client.APIKeys.Get(d.Get("space_id").(string), d.Id()) if _, ok := err.(contentful.NotFoundError); ok { d.SetId("") return nil @@ -114,17 +101,12 @@ func resourceReadAPIKey(d *schema.ResourceData, m interface{}) (err error) { func resourceDeleteAPIKey(d *schema.ResourceData, m interface{}) (err error) { client := m.(*contentful.Contentful) - space, err := client.GetSpace(d.Get("space_id").(string)) - if err != nil { - return err - } - - apiKey, err := space.GetAPIKey(d.Id()) + apiKey, err := client.APIKeys.Get(d.Get("space_id").(string), d.Id()) if err != nil { return err } - return apiKey.Delete() + return client.APIKeys.Delete(d.Get("space_id").(string), apiKey) } func setAPIKeyProperties(d *schema.ResourceData, apiKey *contentful.APIKey) error { diff --git a/resource_contentful_contenttype.go b/resource_contentful_contenttype.go index aa6787b..86518b0 100644 --- a/resource_contentful_contenttype.go +++ b/resource_contentful_contenttype.go @@ -57,10 +57,36 @@ func resourceContentfulContentType() *schema.Resource { Type: schema.TypeString, Required: true, }, + "link_type": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + "items": &schema.Schema{ + Type: schema.TypeSet, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "type": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + "validations": &schema.Schema{ + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "link_type": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + }, + }, + }, "required": &schema.Schema{ Type: schema.TypeBool, Optional: true, - Default: true, + Default: false, }, "localized": &schema.Schema{ Type: schema.TypeBool, @@ -72,6 +98,16 @@ func resourceContentfulContentType() *schema.Resource { Optional: true, Default: false, }, + "omitted": &schema.Schema{ + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "validations": &schema.Schema{ + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, }, }, }, @@ -81,33 +117,56 @@ func resourceContentfulContentType() *schema.Resource { func resourceContentTypeCreate(d *schema.ResourceData, m interface{}) (err error) { client := m.(*contentful.Contentful) + spaceID := d.Get("space_id").(string) - space, err := client.GetSpace(d.Get("space_id").(string)) - if err != nil { - return err + ct := &contentful.ContentType{ + Name: d.Get("name").(string), + DisplayField: d.Get("display_field").(string), + Fields: []*contentful.Field{}, } - ct := space.NewContentType() - ct.Name = d.Get("name").(string) - ct.DisplayField = d.Get("display_field").(string) - ct.Description = d.Get("description").(string) + if description, ok := d.GetOk("description"); ok { + ct.Description = description.(string) + } - for _, field := range d.Get("field").(*schema.Set).List() { - ct.Fields = append(ct.Fields, &contentful.Field{ - ID: field.(map[string]interface{})["id"].(string), - Name: field.(map[string]interface{})["name"].(string), - Type: field.(map[string]interface{})["type"].(string), - Localized: field.(map[string]interface{})["localized"].(bool), - Required: field.(map[string]interface{})["required"].(bool), - Disabled: field.(map[string]interface{})["disabled"].(bool), - }) + for _, rawField := range d.Get("field").(*schema.Set).List() { + field := rawField.(map[string]interface{}) + + contentfulField := &contentful.Field{ + ID: field["id"].(string), + Name: field["name"].(string), + Type: field["type"].(string), + Localized: field["localized"].(bool), + Required: field["required"].(bool), + Disabled: field["disabled"].(bool), + Omitted: field["omitted"].(bool), + } + + if linkType, ok := field["link_type"].(string); ok { + contentfulField.LinkType = linkType + } + + if validations, ok := field["validations"].([]interface{}); ok { + parsedValidations, err := contentful.ParseValidations(validations) + if err != nil { + return err + } + + contentfulField.Validations = parsedValidations + } + + if items := processItems(field["items"].(*schema.Set)); items != nil { + contentfulField.Items = items + } + + ct.Fields = append(ct.Fields, contentfulField) } - if err = ct.Save(); err != nil { + if err = client.ContentTypes.Upsert(spaceID, ct); err != nil { return err } - if err = ct.Activate(); err != nil { + if err = client.ContentTypes.Activate(spaceID, ct); err != nil { //@TODO Maybe delete the CT ? return err } @@ -123,74 +182,85 @@ func resourceContentTypeCreate(d *schema.ResourceData, m interface{}) (err error func resourceContentTypeRead(d *schema.ResourceData, m interface{}) (err error) { client := m.(*contentful.Contentful) + spaceID := d.Get("space_id").(string) - space, err := client.GetSpace(d.Get("space_id").(string)) - if err != nil { - return err - } - - _, err = space.GetContentType(d.Id()) + _, err = client.ContentTypes.Get(spaceID, d.Id()) return err } func resourceContentTypeUpdate(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Contentful) + var existingFields []*contentful.Field + var deletedFields []*contentful.Field - space, err := client.GetSpace(d.Get("space_id").(string)) - if err != nil { - return err - } + client := m.(*contentful.Contentful) + spaceID := d.Get("space_id").(string) - ct, err := space.GetContentType(d.Id()) + ct, err := client.ContentTypes.Get(spaceID, d.Id()) if err != nil { return err } ct.Name = d.Get("name").(string) ct.DisplayField = d.Get("display_field").(string) - ct.Description = d.Get("description").(string) - var fields []*contentful.Field - for _, field := range d.Get("field").(*schema.Set).List() { - fields = append(fields, &contentful.Field{ - ID: field.(map[string]interface{})["id"].(string), - Name: field.(map[string]interface{})["name"].(string), - Type: field.(map[string]interface{})["type"].(string), - Localized: field.(map[string]interface{})["localized"].(bool), - Required: field.(map[string]interface{})["required"].(bool), - Disabled: field.(map[string]interface{})["disabled"].(bool), - }) + if description, ok := d.GetOk("description"); ok { + ct.Description = description.(string) } - ct.Fields = fields + // Figure out if fields were removed + if d.HasChange("field") { + old, new := d.GetChange("field") + + existingFields, deletedFields = checkFieldChanges(old.(*schema.Set), new.(*schema.Set)) - if err = ct.Save(); err != nil { + ct.Fields = existingFields + + if deletedFields != nil { + ct.Fields = append(ct.Fields, deletedFields...) + } + } + + if err = client.ContentTypes.Upsert(spaceID, ct); err != nil { return err } - if err = ct.Activate(); err != nil { + if err = client.ContentTypes.Activate(spaceID, ct); err != nil { //@TODO Maybe delete the CT ? return err } + if deletedFields != nil { + ct.Fields = existingFields + + if err = client.ContentTypes.Upsert(spaceID, ct); err != nil { + return err + } + + if err = client.ContentTypes.Activate(spaceID, ct); err != nil { + //@TODO Maybe delete the CT ? + return err + } + } + return setContentTypeProperties(d, ct) } func resourceContentTypeDelete(d *schema.ResourceData, m interface{}) (err error) { client := m.(*contentful.Contentful) + spaceID := d.Get("space_id").(string) - space, err := client.GetSpace(d.Get("space_id").(string)) + ct, err := client.ContentTypes.Get(spaceID, d.Id()) if err != nil { return err } - ct, err := space.GetContentType(d.Id()) + err = client.ContentTypes.Deactivate(spaceID, ct) if err != nil { return err } - if err = ct.Delete(); err != nil { + if err = client.ContentTypes.Delete(spaceID, ct); err != nil { return err } @@ -205,3 +275,89 @@ func setContentTypeProperties(d *schema.ResourceData, ct *contentful.ContentType return nil } + +func checkFieldChanges(old, new *schema.Set) ([]*contentful.Field, []*contentful.Field) { + var contentfulField *contentful.Field + var existingFields []*contentful.Field + var deletedFields []*contentful.Field + var fieldRemoved bool + + for _, f := range old.List() { + oldField := f.(map[string]interface{}) + + fieldRemoved = true + for _, newField := range new.List() { + if oldField["id"].(string) == newField.(map[string]interface{})["id"].(string) { + fieldRemoved = false + break + } + } + + if fieldRemoved { + deletedFields = append(deletedFields, + &contentful.Field{ + ID: oldField["id"].(string), + Name: oldField["name"].(string), + Type: oldField["type"].(string), + LinkType: oldField["link_type"].(string), + Localized: oldField["localized"].(bool), + Required: oldField["required"].(bool), + Disabled: oldField["disabled"].(bool), + Omitted: true, + }) + } + } + + for _, f := range new.List() { + newField := f.(map[string]interface{}) + + contentfulField = &contentful.Field{ + ID: newField["id"].(string), + Name: newField["name"].(string), + Type: newField["type"].(string), + Localized: newField["localized"].(bool), + Required: newField["required"].(bool), + Disabled: newField["disabled"].(bool), + Omitted: newField["omitted"].(bool), + } + + if linkType, ok := newField["link_type"].(string); ok { + contentfulField.LinkType = linkType + } + + if validations, ok := newField["validations"].([]interface{}); ok { + parsedValidations, _ := contentful.ParseValidations(validations) + + contentfulField.Validations = parsedValidations + } + + if items := processItems(newField["items"].(*schema.Set)); items != nil { + contentfulField.Items = items + } + + existingFields = append(existingFields, contentfulField) + } + + return existingFields, deletedFields +} + +func processItems(fieldItems *schema.Set) *contentful.FieldTypeArrayItem { + var items *contentful.FieldTypeArrayItem + + for _, i := range fieldItems.List() { + item := i.(map[string]interface{}) + + var validations []contentful.FieldValidation + + if fieldValidations, ok := item["validations"].([]interface{}); ok { + validations, _ = contentful.ParseValidations(fieldValidations) + } + + items = &contentful.FieldTypeArrayItem{ + Type: item["type"].(string), + Validations: validations, + LinkType: item["link_type"].(string), + } + } + return items +} diff --git a/resource_contentful_contenttype_test.go b/resource_contentful_contenttype_test.go index 040c838..8a0ca17 100644 --- a/resource_contentful_contenttype_test.go +++ b/resource_contentful_contenttype_test.go @@ -18,12 +18,17 @@ func TestAccContentfulContentType_Basic(t *testing.T) { resource.TestStep{ Config: testAccContentfulContentTypeConfig, Check: resource.TestCheckResourceAttr( - "contentful_contenttype.mycontenttype", "name", "Terraform"), + "contentful_contenttype.mycontenttype", "name", "TF Acc Test CT 1"), }, resource.TestStep{ Config: testAccContentfulContentTypeUpdateConfig, Check: resource.TestCheckResourceAttr( - "contentful_contenttype.mycontenttype", "name", "Terraform name change"), + "contentful_contenttype.mycontenttype", "name", "TF Acc Test CT name change"), + }, + resource.TestStep{ + Config: testAccContentfulContentTypeLinkConfig, + Check: resource.TestCheckResourceAttr( + "contentful_contenttype.mylinked_contenttype", "name", "TF Acc Test Linked CT"), }, }, }) @@ -47,12 +52,7 @@ func testAccCheckContentfulContentTypeExists(n string, contentType *contentful.C client := testAccProvider.Meta().(*contentful.Contentful) - space, err := client.GetSpace(spaceID) - if err != nil { - return fmt.Errorf("No space with this id: %s", rs.Primary.Attributes["space_id"]) - } - - ct, err := space.GetContentType(rs.Primary.ID) + ct, err := client.ContentTypes.Get(spaceID, rs.Primary.ID) if err != nil { return err } @@ -76,16 +76,7 @@ func testAccCheckContentfulContentTypeDestroy(s *terraform.State) (err error) { client := testAccProvider.Meta().(*contentful.Contentful) - space, err := client.GetSpace(spaceID) - - if err != nil { - if _, ok := err.(contentful.NotFoundError); ok { - return nil - } - return fmt.Errorf("Error checking space_id: %s", spaceID) - } - - _, err = space.GetContentType(rs.Primary.ID) + _, err := client.ContentTypes.Get(spaceID, rs.Primary.ID) if _, ok := err.(contentful.NotFoundError); ok { return nil } @@ -97,16 +88,16 @@ func testAccCheckContentfulContentTypeDestroy(s *terraform.State) (err error) { } var testAccContentfulContentTypeConfig = ` -resource "contentful_space" "myspace" { - name = "Terraform Space" -} +// resource "contentful_space" "myspace" { +// name = "TF Acc Test Space" +// } resource "contentful_contenttype" "mycontenttype" { - space_id = "${contentful_space.myspace.id}" - depends_on = ["contentful_space.myspace"] + // space_id = "${contentful_space.myspace.id}" + space_id = "p025n8nykscm" - name = "Terraform" - description = "Terraform Content Type" + name = "TF Acc Test CT 1" + description = "Terraform Acc Test Content Type" display_field = "field1" field { @@ -119,44 +110,85 @@ resource "contentful_contenttype" "mycontenttype" { field { id = "field2" name = "Field 2" - type = "Number" + type = "Integer" required = false } } ` var testAccContentfulContentTypeUpdateConfig = ` -resource "contentful_space" "myspace" { - name = "Terraform Space" -} - resource "contentful_contenttype" "mycontenttype" { space_id = "${contentful_space.myspace.id}" - depends_on = ["contentful_space.myspace"] - name = "Terraform name change" - description = "Terraform Content Type" + name = "TF Acc Test CT name change" + description = "Terraform Acc Test Content Type description change" display_field = "field1" field { id = "field1" - name = "Field 1" + name = "Field 1 name change" type = "Text" required = true } field { - id = "field2" - name = "Field 2" - type = "Number" - required = false + id = "field3" + name = "Field 3 new field" + type = "Integer" + required = true + } +} +` +var testAccContentfulContentTypeLinkConfig = ` +resource "contentful_contenttype" "mycontenttype" { + space_id = "${contentful_space.myspace.id}" + + name = "TF Acc Test CT name change" + description = "Terraform Acc Test Content Type description change" + display_field = "field1" + + field { + id = "field1" + name = "Field 1 name change" + type = "Text" + required = true } field { id = "field3" - name = "Field 3" - type = "Text" + name = "Field 3 new field" + type = "Integer" + required = true + } +} + +resource "contentful_contenttype" "mylinked_contenttype" { + space_id = "${contentful_space.myspace.id}" + + name = "TF Acc Test Linked CT" + description = "Terraform Acc Test Content Type with links" + display_field = "asset_field" + + field { + id = "asset_field" + name = "Asset Field" + type = "Array" + items { + type = "Link" + link_type = "Asset" + } required = true } + + field { + id = "entry_link_field" + name = "Entry Link Field" + type = "Link" + link_type = "Entry" + validations = ["{\"linkContentType\": [\"${contentful_contenttype.mycontenttype.id}\"]}"] + required = false + } + } + ` diff --git a/resource_contentful_locale.go b/resource_contentful_locale.go index 97a041a..c2ef98d 100644 --- a/resource_contentful_locale.go +++ b/resource_contentful_locale.go @@ -50,19 +50,16 @@ func resourceContentfulLocale() *schema.Resource { func resourceCreateLocale(d *schema.ResourceData, m interface{}) (err error) { client := m.(*contentful.Contentful) + spaceID := d.Get("space_id").(string) - space, err := client.GetSpace(d.Get("space_id").(string)) - if err != nil { - return err + locale := &contentful.Locale{ + Name: d.Get("name").(string), + Code: d.Get("code").(string), + FallbackCode: d.Get("fallback_code").(string), + Optional: d.Get("optional").(bool), } - locale := space.NewLocale() - locale.Name = d.Get("name").(string) - locale.Code = d.Get("code").(string) - locale.FallbackCode = d.Get("fallback_code").(string) - locale.Optional = d.Get("optional").(bool) - - err = locale.Save() + err = client.Locales.Upsert(spaceID, locale) if err != nil { return err } @@ -79,13 +76,9 @@ func resourceCreateLocale(d *schema.ResourceData, m interface{}) (err error) { func resourceReadLocale(d *schema.ResourceData, m interface{}) error { client := m.(*contentful.Contentful) + spaceID := d.Get("space_id").(string) - space, err := client.GetSpace(d.Get("space_id").(string)) - if err != nil { - return err - } - - locale, err := space.GetLocale(d.Id()) + locale, err := client.Locales.Get(spaceID, d.Id()) if _, ok := err.(*contentful.NotFoundError); ok { d.SetId("") return nil @@ -100,13 +93,9 @@ func resourceReadLocale(d *schema.ResourceData, m interface{}) error { func resourceUpdateLocale(d *schema.ResourceData, m interface{}) (err error) { client := m.(*contentful.Contentful) + spaceID := d.Get("space_id").(string) - space, err := client.GetSpace(d.Get("space_id").(string)) - if err != nil { - return err - } - - locale, err := space.GetLocale(d.Id()) + locale, err := client.Locales.Get(spaceID, d.Id()) if err != nil { return err } @@ -115,7 +104,8 @@ func resourceUpdateLocale(d *schema.ResourceData, m interface{}) (err error) { locale.Code = d.Get("code").(string) locale.FallbackCode = d.Get("fallback_code").(string) locale.Optional = d.Get("optional").(bool) - err = locale.Save() + + err = client.Locales.Upsert(spaceID, locale) if err != nil { return err } @@ -130,18 +120,14 @@ func resourceUpdateLocale(d *schema.ResourceData, m interface{}) (err error) { func resourceDeleteLocale(d *schema.ResourceData, m interface{}) (err error) { client := m.(*contentful.Contentful) + spaceID := d.Get("space_id").(string) - space, err := client.GetSpace(d.Get("space_id").(string)) - if err != nil { - return err - } - - locale, err := space.GetLocale(d.Id()) + locale, err := client.Locales.Get(spaceID, d.Id()) if err != nil { return err } - err = locale.Delete() + err = client.Locales.Delete(spaceID, locale) if _, ok := err.(*contentful.NotFoundError); ok { return nil } diff --git a/resource_contentful_space.go b/resource_contentful_space.go index 4def47f..310aeca 100644 --- a/resource_contentful_space.go +++ b/resource_contentful_space.go @@ -38,10 +38,12 @@ func resourceContentfulSpace() *schema.Resource { func resourceSpaceCreate(d *schema.ResourceData, m interface{}) (err error) { client := m.(*contentful.Contentful) - space := client.NewSpace() - space.Name = d.Get("name").(string) - space.DefaultLocale = d.Get("default_locale").(string) - err = space.Save() + space := &contentful.Space{ + Name: d.Get("name").(string), + DefaultLocale: d.Get("default_locale").(string), + } + + err = client.Spaces.Upsert(space) if err != nil { return err } @@ -58,9 +60,9 @@ func resourceSpaceCreate(d *schema.ResourceData, m interface{}) (err error) { func resourceSpaceRead(d *schema.ResourceData, m interface{}) error { client := m.(*contentful.Contentful) + spaceID := d.Id() - _, err := client.GetSpace(d.Id()) - + _, err := client.Spaces.Get(spaceID) if _, ok := err.(contentful.NotFoundError); ok { d.SetId("") return nil @@ -71,14 +73,16 @@ func resourceSpaceRead(d *schema.ResourceData, m interface{}) error { func resourceSpaceUpdate(d *schema.ResourceData, m interface{}) (err error) { client := m.(*contentful.Contentful) + spaceID := d.Id() - space, err := client.GetSpace(d.Id()) + space, err := client.Spaces.Get(spaceID) if err != nil { return err } space.Name = d.Get("name").(string) - err = space.Save() + + err = client.Spaces.Upsert(space) if err != nil { return err } @@ -88,13 +92,14 @@ func resourceSpaceUpdate(d *schema.ResourceData, m interface{}) (err error) { func resourceSpaceDelete(d *schema.ResourceData, m interface{}) (err error) { client := m.(*contentful.Contentful) + spaceID := d.Id() - space, err := client.GetSpace(d.Id()) + space, err := client.Spaces.Get(spaceID) if err != nil { return err } - err = space.Delete() + err = client.Spaces.Delete(space) if _, ok := err.(contentful.NotFoundError); ok { return nil } diff --git a/resource_contentful_space_test.go b/resource_contentful_space_test.go index cc5cf82..da1e9e5 100644 --- a/resource_contentful_space_test.go +++ b/resource_contentful_space_test.go @@ -10,6 +10,7 @@ import ( ) func TestAccContentfulSpace_Basic(t *testing.T) { + t.Skip() resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, @@ -18,12 +19,12 @@ func TestAccContentfulSpace_Basic(t *testing.T) { resource.TestStep{ Config: testAccContentfulSpaceConfig, Check: resource.TestCheckResourceAttr( - "contentful_space.myspace", "name", "space-name"), + "contentful_space.myspace", "name", "TF Acc Test Space"), }, resource.TestStep{ Config: testAccContentfulSpaceUpdateConfig, Check: resource.TestCheckResourceAttr( - "contentful_space.myspace", "name", "changed-space-name"), + "contentful_space.myspace", "name", "TF Acc Test Changed Space"), }, }, }) @@ -37,9 +38,9 @@ func testAccCheckContentfulSpaceDestroy(s *terraform.State) error { continue } - space, err := client.GetSpace(rs.Primary.ID) + space, err := client.Spaces.Get(rs.Primary.ID) if err == nil { - return fmt.Errorf("Space %s still exists after destroy", space.ID()) + return fmt.Errorf("Space %s still exists after destroy", space.Sys.ID) } } @@ -48,12 +49,12 @@ func testAccCheckContentfulSpaceDestroy(s *terraform.State) error { var testAccContentfulSpaceConfig = ` resource "contentful_space" "myspace" { - name = "space-name" + name = "TF Acc Test Space" } ` var testAccContentfulSpaceUpdateConfig = ` resource "contentful_space" "myspace" { - name = "changed-space-name" + name = "TF Acc Test Changed Space" } ` diff --git a/resource_contentful_webhook.go b/resource_contentful_webhook.go index db2f9cd..5acce9c 100644 --- a/resource_contentful_webhook.go +++ b/resource_contentful_webhook.go @@ -62,21 +62,18 @@ func resourceContentfulWebhook() *schema.Resource { func resourceCreateWebhook(d *schema.ResourceData, m interface{}) (err error) { client := m.(*contentful.Contentful) + spaceID := d.Get("space_id").(string) - space, err := client.GetSpace(d.Get("space_id").(string)) - if err != nil { - return err + webhook := &contentful.Webhook{ + Name: d.Get("name").(string), + URL: d.Get("url").(string), + Topics: transformTopicsToContentfulFormat(d.Get("topics").([]interface{})), + Headers: transformHeadersToContentfulFormat(d.Get("headers")), + HTTPBasicUsername: d.Get("http_basic_auth_username").(string), + HTTPBasicPassword: d.Get("http_basic_auth_password").(string), } - webhook := space.NewWebhook() - webhook.Name = d.Get("name").(string) - webhook.URL = d.Get("url").(string) - webhook.Topics = transformTopicsToContentfulFormat(d.Get("topics").([]interface{})) - webhook.Headers = transformHeadersToContentfulFormat(d.Get("headers")) - webhook.HTTPBasicUsername = d.Get("http_basic_auth_username").(string) - webhook.HTTPBasicPassword = d.Get("http_basic_auth_password").(string) - - err = webhook.Save() + err = client.Webhooks.Upsert(spaceID, webhook) if err != nil { return err } @@ -93,13 +90,10 @@ func resourceCreateWebhook(d *schema.ResourceData, m interface{}) (err error) { func resourceUpdateWebhook(d *schema.ResourceData, m interface{}) (err error) { client := m.(*contentful.Contentful) + spaceID := d.Get("space_id").(string) + webhookID := d.Id() - space, err := client.GetSpace(d.Get("space_id").(string)) - if err != nil { - return err - } - - webhook, err := space.GetWebhook(d.Id()) + webhook, err := client.Webhooks.Get(spaceID, webhookID) if err != nil { return err } @@ -111,7 +105,7 @@ func resourceUpdateWebhook(d *schema.ResourceData, m interface{}) (err error) { webhook.HTTPBasicUsername = d.Get("http_basic_auth_username").(string) webhook.HTTPBasicPassword = d.Get("http_basic_auth_password").(string) - err = webhook.Save() + err = client.Webhooks.Upsert(spaceID, webhook) if err != nil { return err } @@ -128,13 +122,10 @@ func resourceUpdateWebhook(d *schema.ResourceData, m interface{}) (err error) { func resourceReadWebhook(d *schema.ResourceData, m interface{}) error { client := m.(*contentful.Contentful) + spaceID := d.Get("space_id").(string) + webhookID := d.Id() - space, err := client.GetSpace(d.Get("space_id").(string)) - if err != nil { - return err - } - - webhook, err := space.GetWebhook(d.Id()) + webhook, err := client.Webhooks.Get(spaceID, webhookID) if _, ok := err.(contentful.NotFoundError); ok { d.SetId("") return nil @@ -149,18 +140,15 @@ func resourceReadWebhook(d *schema.ResourceData, m interface{}) error { func resourceDeleteWebhook(d *schema.ResourceData, m interface{}) (err error) { client := m.(*contentful.Contentful) + spaceID := d.Get("space_id").(string) + webhookID := d.Id() - space, err := client.GetSpace(d.Get("space_id").(string)) - if err != nil { - return err - } - - webhook, err := space.GetWebhook(d.Id()) + webhook, err := client.Webhooks.Get(spaceID, webhookID) if err != nil { return err } - err = webhook.Delete() + err = client.Webhooks.Delete(spaceID, webhook) if _, ok := err.(contentful.NotFoundError); ok { return nil } diff --git a/resource_contentful_webhook_test.go b/resource_contentful_webhook_test.go index 21579bc..c35e59f 100644 --- a/resource_contentful_webhook_test.go +++ b/resource_contentful_webhook_test.go @@ -61,15 +61,9 @@ func testAccCheckContentfulWebhookExists(n string, webhook *contentful.Webhook) return fmt.Errorf("No webhook ID is set") } - // sdk client client := testAccProvider.Meta().(*contentful.Contentful) - space, err := client.GetSpace(spaceID) - if err != nil { - return fmt.Errorf("No space with this id: %s", spaceID) - } - - contentfulWebhook, err := space.GetWebhook(rs.Primary.ID) + contentfulWebhook, err := client.Webhooks.Get(spaceID, rs.Primary.ID) if err != nil { return err } @@ -125,15 +119,7 @@ func testAccContentfulWebhookDestroy(s *terraform.State) error { // sdk client client := testAccProvider.Meta().(*contentful.Contentful) - space, err := client.GetSpace(spaceID) - if _, ok := err.(contentful.NotFoundError); ok { - return nil - } - if err != nil { - return err - } - - _, err = space.GetWebhook(rs.Primary.ID) + _, err := client.Webhooks.Get(spaceID, rs.Primary.ID) if _, ok := err.(contentful.NotFoundError); ok { return nil } diff --git a/test.tf b/test.tf deleted file mode 100644 index 03b9836..0000000 --- a/test.tf +++ /dev/null @@ -1,50 +0,0 @@ -provider "contentful" { - cma_token = "" - organization_id = "" -} -resource "contentful_space" "test" { - name = "my-update-space-name" -} - -resource "contentful_webhook" "test" { - name = "b3" - space_id = "${contentful_space.test.id}" - url = "http://yeah-updated.com" - headers = { - "wwwwwwwwwwwwking" = "update just now" - } - topics = ["*.*"] -} - -resource "contentful_apikey" "test" { - space_id = "${contentful_space.test.id}" - name = "foobar3" -} - -output "space_id" { - value = "${contentful_space.test.id}" -} - -output "space_name" { - value = "${contentful_space.test.name}" -} - -output "space_version" { - value = "${contentful_space.test.version}" -} - - -output "webhook_id" { - value = "${contentful_webhook.test.id}" -} - -output "webhook_name" { - value = "${contentful_webhook.test.name}" -} - -# needs special plan -# resource "contentful_locale" "test" { - # space_id = "${contentful_space.test.id}" - # name = "foo" - # code = "ru" -# } From 779dd716f6d38d9961e0c37ff3025eb57428bdf3 Mon Sep 17 00:00:00 2001 From: Tolga Akyuz Date: Wed, 29 Mar 2017 15:48:55 +0200 Subject: [PATCH 034/192] [Added] locale resource and test --- resource_contentful_locale.go | 36 +++++- resource_contentful_locale_test.go | 189 +++++++++++++++++++++++++++++ 2 files changed, 220 insertions(+), 5 deletions(-) create mode 100644 resource_contentful_locale_test.go diff --git a/resource_contentful_locale.go b/resource_contentful_locale.go index c2ef98d..3e9ef70 100644 --- a/resource_contentful_locale.go +++ b/resource_contentful_locale.go @@ -29,7 +29,6 @@ func resourceContentfulLocale() *schema.Resource { Type: schema.TypeString, Required: true, }, - // Locale specific props "code": &schema.Schema{ Type: schema.TypeString, Required: true, @@ -44,6 +43,16 @@ func resourceContentfulLocale() *schema.Resource { Optional: true, Default: false, }, + "cda": &schema.Schema{ + Type: schema.TypeBool, + Optional: true, + Default: true, + }, + "cma": &schema.Schema{ + Type: schema.TypeBool, + Optional: true, + Default: false, + }, }, } } @@ -57,6 +66,8 @@ func resourceCreateLocale(d *schema.ResourceData, m interface{}) (err error) { Code: d.Get("code").(string), FallbackCode: d.Get("fallback_code").(string), Optional: d.Get("optional").(bool), + CDA: d.Get("cda").(bool), + CMA: d.Get("cma").(bool), } err = client.Locales.Upsert(spaceID, locale) @@ -77,8 +88,9 @@ func resourceCreateLocale(d *schema.ResourceData, m interface{}) (err error) { func resourceReadLocale(d *schema.ResourceData, m interface{}) error { client := m.(*contentful.Contentful) spaceID := d.Get("space_id").(string) + localeID := d.Id() - locale, err := client.Locales.Get(spaceID, d.Id()) + locale, err := client.Locales.Get(spaceID, localeID) if _, ok := err.(*contentful.NotFoundError); ok { d.SetId("") return nil @@ -94,8 +106,9 @@ func resourceReadLocale(d *schema.ResourceData, m interface{}) error { func resourceUpdateLocale(d *schema.ResourceData, m interface{}) (err error) { client := m.(*contentful.Contentful) spaceID := d.Get("space_id").(string) + localeID := d.Id() - locale, err := client.Locales.Get(spaceID, d.Id()) + locale, err := client.Locales.Get(spaceID, localeID) if err != nil { return err } @@ -104,6 +117,8 @@ func resourceUpdateLocale(d *schema.ResourceData, m interface{}) (err error) { locale.Code = d.Get("code").(string) locale.FallbackCode = d.Get("fallback_code").(string) locale.Optional = d.Get("optional").(bool) + locale.CDA = d.Get("cda").(bool) + locale.CMA = d.Get("cma").(bool) err = client.Locales.Upsert(spaceID, locale) if err != nil { @@ -121,8 +136,9 @@ func resourceUpdateLocale(d *schema.ResourceData, m interface{}) (err error) { func resourceDeleteLocale(d *schema.ResourceData, m interface{}) (err error) { client := m.(*contentful.Contentful) spaceID := d.Get("space_id").(string) + localeID := d.Id() - locale, err := client.Locales.Get(spaceID, d.Id()) + locale, err := client.Locales.Get(spaceID, localeID) if err != nil { return err } @@ -150,7 +166,7 @@ func setLocaleProperties(d *schema.ResourceData, locale *contentful.Locale) erro return err } - err = d.Set("fallbackCode", locale.FallbackCode) + err = d.Set("fallback_code", locale.FallbackCode) if err != nil { return err } @@ -160,5 +176,15 @@ func setLocaleProperties(d *schema.ResourceData, locale *contentful.Locale) erro return err } + err = d.Set("cda", locale.CDA) + if err != nil { + return err + } + + err = d.Set("cma", locale.CMA) + if err != nil { + return err + } + return nil } diff --git a/resource_contentful_locale_test.go b/resource_contentful_locale_test.go new file mode 100644 index 0000000..f6e06aa --- /dev/null +++ b/resource_contentful_locale_test.go @@ -0,0 +1,189 @@ +package main + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + contentful "github.com/tolgaakyuz/contentful-go" +) + +func TestAccContentfulLocales_Basic(t *testing.T) { + var locale contentful.Locale + + spaceName := fmt.Sprintf("space-name-%s", acctest.RandString(3)) + name := fmt.Sprintf("locale-name-%s", acctest.RandString(3)) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccContentfulLocaleDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccContentfulLocaleConfig(spaceName, name), + Check: resource.ComposeTestCheckFunc( + testAccCheckContentfulLocaleExists("contentful_locale.mylocale", &locale), + testAccCheckContentfulLocaleAttributes(&locale, map[string]interface{}{ + "name": name, + "code": "de", + "fallback_code": "en-US", + "optional": false, + "cda": false, + "cma": true, + }), + ), + }, + resource.TestStep{ + Config: testAccContentfulLocaleUpdateConfig(spaceName, name), + Check: resource.ComposeTestCheckFunc( + testAccCheckContentfulLocaleExists("contentful_locale.mylocale", &locale), + testAccCheckContentfulLocaleAttributes(&locale, map[string]interface{}{ + "name": fmt.Sprintf("%s-updated", name), + "code": "es", + "fallback_code": "en-US", + "optional": true, + "cda": true, + "cma": false, + }), + ), + }, + }, + }) +} + +func testAccCheckContentfulLocaleExists(n string, locale *contentful.Locale) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not Found: %s", n) + } + + spaceID := rs.Primary.Attributes["space_id"] + if spaceID == "" { + return fmt.Errorf("No space_id is set") + } + + localeID := rs.Primary.ID + if localeID == "" { + return fmt.Errorf("No locale ID is set") + } + + client := testAccProvider.Meta().(*contentful.Contentful) + + contentfulLocale, err := client.Locales.Get(spaceID, localeID) + if err != nil { + return err + } + + *locale = *contentfulLocale + + return nil + } +} + +func testAccCheckContentfulLocaleAttributes(locale *contentful.Locale, attrs map[string]interface{}) resource.TestCheckFunc { + return func(s *terraform.State) error { + name := attrs["name"].(string) + if locale.Name != name { + return fmt.Errorf("Locale name does not match: %s, %s", locale.Name, name) + } + + code := attrs["code"].(string) + if locale.Code != code { + return fmt.Errorf("Locale code does not match: %s, %s", locale.Code, code) + } + + fallbackCode := attrs["fallback_code"].(string) + if locale.FallbackCode != fallbackCode { + return fmt.Errorf("Locale fallback code does not match: %s, %s", locale.FallbackCode, fallbackCode) + } + + isOptional := attrs["optional"].(bool) + if locale.Optional != isOptional { + return fmt.Errorf("Locale options value does not match: %t, %t", locale.Optional, isOptional) + } + + isCDA := attrs["cda"].(bool) + if locale.CDA != isCDA { + return fmt.Errorf("Locale cda does not match: %t, %t", locale.CDA, isCDA) + } + + isCMA := attrs["cma"].(bool) + if locale.CMA != isCMA { + return fmt.Errorf("Locale cma does not match: %t, %t", locale.CMA, isCMA) + } + + return nil + } +} + +func testAccContentfulLocaleDestroy(s *terraform.State) error { + for _, rs := range s.RootModule().Resources { + if rs.Type != "contentful_locale" { + continue + } + + spaceID := rs.Primary.Attributes["space_id"] + if spaceID == "" { + return fmt.Errorf("No space_id is set") + } + + localeID := rs.Primary.ID + if localeID == "" { + return fmt.Errorf("No locale ID is set") + } + + client := testAccProvider.Meta().(*contentful.Contentful) + + _, err := client.Locales.Get(spaceID, localeID) + if _, ok := err.(contentful.NotFoundError); ok { + return nil + } + + return fmt.Errorf("Locale still exists with id: %s", localeID) + } + + return nil +} + +func testAccContentfulLocaleConfig(spaceName, name string) string { + return fmt.Sprintf(` +resource "contentful_space" "myspace" { + name = "%s" + default_locale = "en-US" +} + +resource "contentful_locale" "mylocale" { + space_id = "${contentful_space.myspace.id}" + + name = "%s" + code = "de" + fallback_code = "en-US" + optional = false + cda = false + cma = true +} +`, spaceName, name) +} + +func testAccContentfulLocaleUpdateConfig(spaceName, name string) string { + return fmt.Sprintf(` +resource "contentful_space" "myspace" { + name = "%s" + default_locale = "en-US" +} + +resource "contentful_locale" "mylocale" { + space_id = "${contentful_space.myspace.id}" + + name = "%s-updated" + code = "es" + fallback_code = "en-US" + optional = true + cda = true + cma = false +} +`, spaceName, name) +} From 79a3a1ab5f19c24ad51011a21597a77eb08b6ead Mon Sep 17 00:00:00 2001 From: Tolga Akyuz Date: Mon, 27 Mar 2017 21:21:22 +0200 Subject: [PATCH 035/192] apikey resource fixes and testing --- resource_contentful_apikey.go | 36 +++---- resource_contentful_apikey_test.go | 153 +++++++++++++++++++++++++++++ 2 files changed, 171 insertions(+), 18 deletions(-) create mode 100644 resource_contentful_apikey_test.go diff --git a/resource_contentful_apikey.go b/resource_contentful_apikey.go index 8eddd60..cb0a324 100644 --- a/resource_contentful_apikey.go +++ b/resource_contentful_apikey.go @@ -29,14 +29,9 @@ func resourceContentfulAPIKey() *schema.Resource { Type: schema.TypeString, Required: true, }, - // Webhook specific props - "delivery_api_key": &schema.Schema{ + "description": &schema.Schema{ Type: schema.TypeString, - Computed: true, - }, - "preview_api_key": &schema.Schema{ - Type: schema.TypeString, - Computed: true, + Optional: true, }, }, } @@ -46,7 +41,8 @@ func resourceCreateAPIKey(d *schema.ResourceData, m interface{}) (err error) { client := m.(*contentful.Contentful) apiKey := &contentful.APIKey{ - Name: d.Get("name").(string), + Name: d.Get("name").(string), + Description: d.Get("description").(string), } err = client.APIKeys.Upsert(d.Get("space_id").(string), apiKey) @@ -65,14 +61,18 @@ func resourceCreateAPIKey(d *schema.ResourceData, m interface{}) (err error) { func resourceUpdateAPIKey(d *schema.ResourceData, m interface{}) (err error) { client := m.(*contentful.Contentful) + spaceID := d.Get("space_id").(string) + apiKeyID := d.Id() - apiKey, err := client.APIKeys.Get(d.Get("space_id").(string), d.Id()) + apiKey, err := client.APIKeys.Get(spaceID, apiKeyID) if err != nil { return err } apiKey.Name = d.Get("name").(string) - err = client.APIKeys.Upsert(d.Get("space_id").(string), apiKey) + apiKey.Description = d.Get("description").(string) + + err = client.APIKeys.Upsert(spaceID, apiKey) if err != nil { return err } @@ -88,8 +88,10 @@ func resourceUpdateAPIKey(d *schema.ResourceData, m interface{}) (err error) { func resourceReadAPIKey(d *schema.ResourceData, m interface{}) (err error) { client := m.(*contentful.Contentful) + spaceID := d.Get("space_id").(string) + apiKeyID := d.Id() - apiKey, err := client.APIKeys.Get(d.Get("space_id").(string), d.Id()) + apiKey, err := client.APIKeys.Get(spaceID, apiKeyID) if _, ok := err.(contentful.NotFoundError); ok { d.SetId("") return nil @@ -100,13 +102,15 @@ func resourceReadAPIKey(d *schema.ResourceData, m interface{}) (err error) { func resourceDeleteAPIKey(d *schema.ResourceData, m interface{}) (err error) { client := m.(*contentful.Contentful) + spaceID := d.Get("space_id").(string) + apiKeyID := d.Id() - apiKey, err := client.APIKeys.Get(d.Get("space_id").(string), d.Id()) + apiKey, err := client.APIKeys.Get(spaceID, apiKeyID) if err != nil { return err } - return client.APIKeys.Delete(d.Get("space_id").(string), apiKey) + return client.APIKeys.Delete(spaceID, apiKey) } func setAPIKeyProperties(d *schema.ResourceData, apiKey *contentful.APIKey) error { @@ -122,11 +126,7 @@ func setAPIKeyProperties(d *schema.ResourceData, apiKey *contentful.APIKey) erro return err } - if err := d.Set("delivery_api_key", apiKey.AccessToken); err != nil { - return err - } - - if err := d.Set("preview_api_key", apiKey.PreviewAPIKey.Sys.ID); err != nil { + if err := d.Set("description", apiKey.Description); err != nil { return err } diff --git a/resource_contentful_apikey_test.go b/resource_contentful_apikey_test.go new file mode 100644 index 0000000..bc1542a --- /dev/null +++ b/resource_contentful_apikey_test.go @@ -0,0 +1,153 @@ +package main + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + contentful "github.com/tolgaakyuz/contentful-go" +) + +func TestAccContentfulAPIKey_Basic(t *testing.T) { + var apiKey contentful.APIKey + + spaceName := fmt.Sprintf("space-name-%s", acctest.RandString(3)) + name := fmt.Sprintf("apikey-name-%s", acctest.RandString(3)) + description := fmt.Sprintf("apikey-description-%s", acctest.RandString(3)) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccContentfulAPIKeyDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccContentfulAPIKeyConfig(spaceName, name, description), + Check: resource.ComposeTestCheckFunc( + testAccCheckContentfulAPIKeyExists("contentful_apikey.myapikey", &apiKey), + testAccCheckContentfulAPIKeyAttributes(&apiKey, map[string]interface{}{ + "name": name, + "description": description, + }), + ), + }, + resource.TestStep{ + Config: testAccContentfulAPIKeyUpdateConfig(spaceName, name, description), + Check: resource.ComposeTestCheckFunc( + testAccCheckContentfulAPIKeyExists("contentful_apikey.myapikey", &apiKey), + testAccCheckContentfulAPIKeyAttributes(&apiKey, map[string]interface{}{ + "name": fmt.Sprintf("%s-updated", name), + "description": fmt.Sprintf("%s-updated", description), + }), + ), + }, + }, + }) +} + +func testAccCheckContentfulAPIKeyExists(n string, apiKey *contentful.APIKey) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not Found: %s", n) + } + + spaceID := rs.Primary.Attributes["space_id"] + if spaceID == "" { + return fmt.Errorf("No space_id is set") + } + + apiKeyID := rs.Primary.ID + if apiKeyID == "" { + return fmt.Errorf("No api key ID is set") + } + + client := testAccProvider.Meta().(*contentful.Contentful) + + contentfulAPIKey, err := client.APIKeys.Get(spaceID, apiKeyID) + if err != nil { + return err + } + + *apiKey = *contentfulAPIKey + + return nil + } +} + +func testAccCheckContentfulAPIKeyAttributes(apiKey *contentful.APIKey, attrs map[string]interface{}) resource.TestCheckFunc { + return func(s *terraform.State) error { + name := attrs["name"].(string) + if apiKey.Name != name { + return fmt.Errorf("APIKey name does not match: %s, %s", apiKey.Name, name) + } + + description := attrs["description"].(string) + if apiKey.Description != description { + return fmt.Errorf("APIKey description does not match: %s, %s", apiKey.Description, description) + } + + return nil + } +} + +func testAccContentfulAPIKeyDestroy(s *terraform.State) error { + for _, rs := range s.RootModule().Resources { + if rs.Type != "contentful_apikey" { + continue + } + + // get space id from resource data + spaceID := rs.Primary.Attributes["space_id"] + if spaceID == "" { + return fmt.Errorf("No space_id is set") + } + + apiKeyID := rs.Primary.ID + if apiKeyID == "" { + return fmt.Errorf("No apikey ID is set") + } + + client := testAccProvider.Meta().(*contentful.Contentful) + + _, err := client.APIKeys.Get(spaceID, apiKeyID) + if _, ok := err.(contentful.NotFoundError); ok { + return nil + } + + return fmt.Errorf("Api Key still exists with id: %s", rs.Primary.ID) + } + + return nil +} + +func testAccContentfulAPIKeyConfig(spaceName, name, description string) string { + return fmt.Sprintf(` +resource "contentful_space" "myspace" { + name = "%s" +} + +resource "contentful_apikey" "myapikey" { + space_id = "${contentful_space.myspace.id}" + + name = "%s" + description = "%s" +} +`, spaceName, name, description) +} + +func testAccContentfulAPIKeyUpdateConfig(spaceName, name, description string) string { + return fmt.Sprintf(` +resource "contentful_space" "myspace" { + name = "%s" +} + +resource "contentful_apikey" "myapikey" { + space_id = "${contentful_space.myspace.id}" + + name = "%s-updated" + description = "%s-updated" +} +`, spaceName, name, description) +} From 77c3c164c00a36e3809947f9bb9e569cb0c1db0c Mon Sep 17 00:00:00 2001 From: Luis Neves Date: Thu, 30 Mar 2017 17:39:08 +0200 Subject: [PATCH 036/192] [Fix] removed hardcoded space_id from test --- resource_contentful_contenttype.go | 4 +++- resource_contentful_contenttype_test.go | 3 +-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/resource_contentful_contenttype.go b/resource_contentful_contenttype.go index 86518b0..0e3929d 100644 --- a/resource_contentful_contenttype.go +++ b/resource_contentful_contenttype.go @@ -208,7 +208,6 @@ func resourceContentTypeUpdate(d *schema.ResourceData, m interface{}) (err error ct.Description = description.(string) } - // Figure out if fields were removed if d.HasChange("field") { old, new := d.GetChange("field") @@ -221,6 +220,9 @@ func resourceContentTypeUpdate(d *schema.ResourceData, m interface{}) (err error } } + // To remove a field from a content type 4 API calls need to be made. + // Ommit the removed fields and publish the new version of the content type, + // followed by the field removal and final publish. if err = client.ContentTypes.Upsert(spaceID, ct); err != nil { return err } diff --git a/resource_contentful_contenttype_test.go b/resource_contentful_contenttype_test.go index 8a0ca17..cd1fcc5 100644 --- a/resource_contentful_contenttype_test.go +++ b/resource_contentful_contenttype_test.go @@ -93,8 +93,7 @@ var testAccContentfulContentTypeConfig = ` // } resource "contentful_contenttype" "mycontenttype" { - // space_id = "${contentful_space.myspace.id}" - space_id = "p025n8nykscm" + space_id = "${contentful_space.myspace.id}" name = "TF Acc Test CT 1" description = "Terraform Acc Test Content Type" From e1d027a165a134f3ebb8018c83ab0cc7c5b11ffa Mon Sep 17 00:00:00 2001 From: Anthony Stanton Date: Mon, 27 Nov 2017 17:25:59 +0100 Subject: [PATCH 037/192] Remove unused id field Fixes #14. --- resource_contentful_apikey.go | 4 ---- resource_contentful_contenttype.go | 4 ---- resource_contentful_locale.go | 4 ---- resource_contentful_space.go | 4 ---- resource_contentful_webhook.go | 4 ---- 5 files changed, 20 deletions(-) diff --git a/resource_contentful_apikey.go b/resource_contentful_apikey.go index cb0a324..1874f53 100644 --- a/resource_contentful_apikey.go +++ b/resource_contentful_apikey.go @@ -13,10 +13,6 @@ func resourceContentfulAPIKey() *schema.Resource { Delete: resourceDeleteAPIKey, Schema: map[string]*schema.Schema{ - "id": &schema.Schema{ - Type: schema.TypeString, - Computed: true, - }, "version": &schema.Schema{ Type: schema.TypeInt, Computed: true, diff --git a/resource_contentful_contenttype.go b/resource_contentful_contenttype.go index 0e3929d..bee476a 100644 --- a/resource_contentful_contenttype.go +++ b/resource_contentful_contenttype.go @@ -18,10 +18,6 @@ func resourceContentfulContentType() *schema.Resource { Required: true, ForceNew: true, }, - "id": &schema.Schema{ - Type: schema.TypeString, - Computed: true, - }, "version": &schema.Schema{ Type: schema.TypeInt, Computed: true, diff --git a/resource_contentful_locale.go b/resource_contentful_locale.go index 3e9ef70..9983222 100644 --- a/resource_contentful_locale.go +++ b/resource_contentful_locale.go @@ -13,10 +13,6 @@ func resourceContentfulLocale() *schema.Resource { Delete: resourceDeleteLocale, Schema: map[string]*schema.Schema{ - "id": &schema.Schema{ - Type: schema.TypeString, - Computed: true, - }, "version": &schema.Schema{ Type: schema.TypeInt, Computed: true, diff --git a/resource_contentful_space.go b/resource_contentful_space.go index 310aeca..ee1d4e1 100644 --- a/resource_contentful_space.go +++ b/resource_contentful_space.go @@ -13,10 +13,6 @@ func resourceContentfulSpace() *schema.Resource { Delete: resourceSpaceDelete, Schema: map[string]*schema.Schema{ - "id": &schema.Schema{ - Type: schema.TypeString, - Computed: true, - }, "version": &schema.Schema{ Type: schema.TypeInt, Computed: true, diff --git a/resource_contentful_webhook.go b/resource_contentful_webhook.go index 5acce9c..e7830bd 100644 --- a/resource_contentful_webhook.go +++ b/resource_contentful_webhook.go @@ -13,10 +13,6 @@ func resourceContentfulWebhook() *schema.Resource { Delete: resourceDeleteWebhook, Schema: map[string]*schema.Schema{ - "id": &schema.Schema{ - Type: schema.TypeString, - Computed: true, - }, "version": &schema.Schema{ Type: schema.TypeInt, Computed: true, From 9ac9d75d432ef37393de17a28e154663b09ce093 Mon Sep 17 00:00:00 2001 From: Anthony Stanton Date: Mon, 27 Nov 2017 17:34:32 +0100 Subject: [PATCH 038/192] Bump Golang version --- Dockerfile-test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile-test b/Dockerfile-test index 12e7961..5e5a912 100644 --- a/Dockerfile-test +++ b/Dockerfile-test @@ -1,4 +1,4 @@ -FROM golang:1.8 +FROM golang:1.9 WORKDIR /go/src/github.com/danihodovic/contentful-terraform From 123cc81ecdabbbe463cab557fbed1808b1b4a464 Mon Sep 17 00:00:00 2001 From: Khaled Garbaya Date: Fri, 1 Dec 2017 15:17:03 +0100 Subject: [PATCH 039/192] Update Contentful description --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d611486..4ddae03 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,8 @@ Terraform Provider for [Contentful's](https://www.contentful.com) Content Manage # About -[Contentful](https://www.contentful.com) is a content management platform for web applications, mobile apps and connected devices. It allows you to create, edit & manage content in the cloud and publish it anywhere via a powerful API. Contentful offers tools for managing editorial teams and enabling cooperation between organizations. + +[Contentful](https://www.contentful.com) provides a content infrastructure for digital teams to power content in websites, apps, and devices. Unlike a CMS, Contentful was built to integrate with the modern software stack. It offers a central hub for structured content, powerful management and delivery APIs, and a customizable web app that enable developers and content creators to ship digital products faster. [Terraform](https://www.terraform.io) is a tool for building, changing, and versioning infrastructure safely and efficiently. Terraform can manage existing and popular service providers as well as custom in-house solutions. From 7434f3691ff34ef5117fdcf66878ccf88fe690aa Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Wed, 8 Apr 2020 16:29:50 +0200 Subject: [PATCH 040/192] local-setup --- Dockerfile-test | 6 +-- constants.go | 11 +++--- install-dependencies.sh | 2 +- provider.go | 6 +-- provider_test.go | 2 +- resource_contentful_apikey.go | 18 ++++----- resource_contentful_apikey_test.go | 6 +-- resource_contentful_contenttype.go | 52 ++++++++++++------------- resource_contentful_contenttype_test.go | 22 +++++------ resource_contentful_locale.go | 26 ++++++------- resource_contentful_locale_test.go | 34 ++++++++-------- resource_contentful_space.go | 16 ++++---- resource_contentful_space_test.go | 10 ++--- resource_contentful_webhook.go | 28 ++++++------- resource_contentful_webhook_test.go | 36 ++++++++--------- 15 files changed, 138 insertions(+), 137 deletions(-) diff --git a/Dockerfile-test b/Dockerfile-test index 5e5a912..72b719c 100644 --- a/Dockerfile-test +++ b/Dockerfile-test @@ -1,11 +1,11 @@ FROM golang:1.9 -WORKDIR /go/src/github.com/danihodovic/contentful-terraform +WORKDIR /go/src/github.com/labd/terraform-contentful # http://stackoverflow.com/questions/39278756/cache-go-get-in-docker-build -COPY ./install-dependencies.sh /go/src/github.com/danihodovic/contentful-terraform/ +COPY ./install-dependencies.sh /go/src/github.com/labd/terraform-contentful RUN ./install-dependencies.sh -COPY . /go/src/github.com/danihodovic/contentful-terraform +COPY . /go/src/github.com/labd/terraform-contentful CMD go test -v diff --git a/constants.go b/constants.go index 5c8f977..5ea01bd 100644 --- a/constants.go +++ b/constants.go @@ -4,13 +4,14 @@ import ( "errors" ) +// noinspection GoUnusedGlobalVariable var ( baseURL = "https://api.contentful.com" contentfulContentType = "application/vnd.contentful.management.v1+json" // User friendly errors we return - errorUnauthorized = errors.New("401 Unauthorized. Is the CMA token valid?") - errorSpaceNotFound = errors.New("Space not found") - errorOrganizationNotFound = errors.New("Organization not found") - errorLocaleNotFound = errors.New("Locale not found") - errorWebhookNotFound = errors.New("The webhook could not be found") + errorUnauthorized = errors.New("401 Unauthorized. Is the CMA token valid") + errorSpaceNotFound = errors.New("space not found") + errorOrganizationNotFound = errors.New("organization not found") + errorLocaleNotFound = errors.New("locale not found") + errorWebhookNotFound = errors.New("the webhook could not be found") ) diff --git a/install-dependencies.sh b/install-dependencies.sh index 656d26a..64a0a61 100755 --- a/install-dependencies.sh +++ b/install-dependencies.sh @@ -4,4 +4,4 @@ go get github.com/hashicorp/terraform/terraform go get github.com/hashicorp/terraform/helper/resource go get github.com/hashicorp/terraform/helper/schema -go get github.com/tolgaakyuz/contentful-go +go get github.com/labd/contentful-go diff --git a/provider.go b/provider.go index 9e47ad8..945fd71 100644 --- a/provider.go +++ b/provider.go @@ -5,20 +5,20 @@ import ( "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/terraform" - contentful "github.com/tolgaakyuz/contentful-go" + contentful "github.com/labd/contentful-go" ) // Provider does shit func Provider() terraform.ResourceProvider { return &schema.Provider{ Schema: map[string]*schema.Schema{ - "cma_token": &schema.Schema{ + "cma_token": { Type: schema.TypeString, Required: true, DefaultFunc: schema.EnvDefaultFunc("CONTENTFUL_MANAGEMENT_TOKEN", nil), Description: "The Contentful Management API token", }, - "organization_id": &schema.Schema{ + "organization_id": { Type: schema.TypeString, Required: true, DefaultFunc: schema.EnvDefaultFunc("CONTENTFUL_ORGANIZATION_ID", nil), diff --git a/provider_test.go b/provider_test.go index 2ca91c1..8ff6fb1 100644 --- a/provider_test.go +++ b/provider_test.go @@ -25,7 +25,7 @@ func TestProvider(t *testing.T) { } func TestProvider_impl(t *testing.T) { - var _ terraform.ResourceProvider = Provider() + var _ = Provider() } func testAccPreCheck(t *testing.T) { diff --git a/resource_contentful_apikey.go b/resource_contentful_apikey.go index 1874f53..7d3b787 100644 --- a/resource_contentful_apikey.go +++ b/resource_contentful_apikey.go @@ -2,7 +2,7 @@ package main import ( "github.com/hashicorp/terraform/helper/schema" - contentful "github.com/tolgaakyuz/contentful-go" + contentful "github.com/labd/contentful-go" ) func resourceContentfulAPIKey() *schema.Resource { @@ -13,19 +13,19 @@ func resourceContentfulAPIKey() *schema.Resource { Delete: resourceDeleteAPIKey, Schema: map[string]*schema.Schema{ - "version": &schema.Schema{ + "version": { Type: schema.TypeInt, Computed: true, }, - "space_id": &schema.Schema{ + "space_id": { Type: schema.TypeString, Required: true, }, - "name": &schema.Schema{ + "name": { Type: schema.TypeString, Required: true, }, - "description": &schema.Schema{ + "description": { Type: schema.TypeString, Optional: true, }, @@ -34,7 +34,7 @@ func resourceContentfulAPIKey() *schema.Resource { } func resourceCreateAPIKey(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Contentful) + client := m.(*contentful.Client) apiKey := &contentful.APIKey{ Name: d.Get("name").(string), @@ -56,7 +56,7 @@ func resourceCreateAPIKey(d *schema.ResourceData, m interface{}) (err error) { } func resourceUpdateAPIKey(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Contentful) + client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) apiKeyID := d.Id() @@ -83,7 +83,7 @@ func resourceUpdateAPIKey(d *schema.ResourceData, m interface{}) (err error) { } func resourceReadAPIKey(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Contentful) + client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) apiKeyID := d.Id() @@ -97,7 +97,7 @@ func resourceReadAPIKey(d *schema.ResourceData, m interface{}) (err error) { } func resourceDeleteAPIKey(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Contentful) + client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) apiKeyID := d.Id() diff --git a/resource_contentful_apikey_test.go b/resource_contentful_apikey_test.go index bc1542a..5531c69 100644 --- a/resource_contentful_apikey_test.go +++ b/resource_contentful_apikey_test.go @@ -7,7 +7,7 @@ import ( "github.com/hashicorp/terraform/helper/acctest" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" - contentful "github.com/tolgaakyuz/contentful-go" + contentful "github.com/labd/contentful-go" ) func TestAccContentfulAPIKey_Basic(t *testing.T) { @@ -63,7 +63,7 @@ func testAccCheckContentfulAPIKeyExists(n string, apiKey *contentful.APIKey) res return fmt.Errorf("No api key ID is set") } - client := testAccProvider.Meta().(*contentful.Contentful) + client := testAccProvider.Meta().(*contentful.Client) contentfulAPIKey, err := client.APIKeys.Get(spaceID, apiKeyID) if err != nil { @@ -109,7 +109,7 @@ func testAccContentfulAPIKeyDestroy(s *terraform.State) error { return fmt.Errorf("No apikey ID is set") } - client := testAccProvider.Meta().(*contentful.Contentful) + client := testAccProvider.Meta().(*contentful.Client) _, err := client.APIKeys.Get(spaceID, apiKeyID) if _, ok := err.(contentful.NotFoundError); ok { diff --git a/resource_contentful_contenttype.go b/resource_contentful_contenttype.go index bee476a..b261ba7 100644 --- a/resource_contentful_contenttype.go +++ b/resource_contentful_contenttype.go @@ -2,7 +2,7 @@ package main import ( "github.com/hashicorp/terraform/helper/schema" - contentful "github.com/tolgaakyuz/contentful-go" + contentful "github.com/labd/contentful-go" ) func resourceContentfulContentType() *schema.Resource { @@ -13,93 +13,93 @@ func resourceContentfulContentType() *schema.Resource { Delete: resourceContentTypeDelete, Schema: map[string]*schema.Schema{ - "space_id": &schema.Schema{ + "space_id": { Type: schema.TypeString, Required: true, ForceNew: true, }, - "version": &schema.Schema{ + "version": { Type: schema.TypeInt, Computed: true, }, - "name": &schema.Schema{ + "name": { Type: schema.TypeString, Required: true, }, - "description": &schema.Schema{ + "description": { Type: schema.TypeString, Optional: true, }, - "display_field": &schema.Schema{ + "display_field": { Type: schema.TypeString, Required: true, }, - "field": &schema.Schema{ + "field": { Type: schema.TypeSet, Required: true, MinItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ - "id": &schema.Schema{ + "id": { Type: schema.TypeString, Required: true, }, - "name": &schema.Schema{ + "name": { Type: schema.TypeString, Required: true, }, //@TODO Add ValidateFunc to validate field type - "type": &schema.Schema{ + "type": { Type: schema.TypeString, Required: true, }, - "link_type": &schema.Schema{ + "link_type": { Type: schema.TypeString, Optional: true, }, - "items": &schema.Schema{ + "items": { Type: schema.TypeSet, Optional: true, MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ - "type": &schema.Schema{ + "type": { Type: schema.TypeString, Required: true, }, - "validations": &schema.Schema{ + "validations": { Type: schema.TypeList, Optional: true, Elem: &schema.Schema{Type: schema.TypeString}, }, - "link_type": &schema.Schema{ + "link_type": { Type: schema.TypeString, Required: true, }, }, }, }, - "required": &schema.Schema{ + "required": { Type: schema.TypeBool, Optional: true, Default: false, }, - "localized": &schema.Schema{ + "localized": { Type: schema.TypeBool, Optional: true, Default: false, }, - "disabled": &schema.Schema{ + "disabled": { Type: schema.TypeBool, Optional: true, Default: false, }, - "omitted": &schema.Schema{ + "omitted": { Type: schema.TypeBool, Optional: true, Default: false, }, - "validations": &schema.Schema{ + "validations": { Type: schema.TypeList, Optional: true, Elem: &schema.Schema{Type: schema.TypeString}, @@ -112,7 +112,7 @@ func resourceContentfulContentType() *schema.Resource { } func resourceContentTypeCreate(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Contentful) + client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) ct := &contentful.ContentType{ @@ -177,7 +177,7 @@ func resourceContentTypeCreate(d *schema.ResourceData, m interface{}) (err error } func resourceContentTypeRead(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Contentful) + client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) _, err = client.ContentTypes.Get(spaceID, d.Id()) @@ -189,7 +189,7 @@ func resourceContentTypeUpdate(d *schema.ResourceData, m interface{}) (err error var existingFields []*contentful.Field var deletedFields []*contentful.Field - client := m.(*contentful.Contentful) + client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) ct, err := client.ContentTypes.Get(spaceID, d.Id()) @@ -205,9 +205,9 @@ func resourceContentTypeUpdate(d *schema.ResourceData, m interface{}) (err error } if d.HasChange("field") { - old, new := d.GetChange("field") + old, nw := d.GetChange("field") - existingFields, deletedFields = checkFieldChanges(old.(*schema.Set), new.(*schema.Set)) + existingFields, deletedFields = checkFieldChanges(old.(*schema.Set), nw.(*schema.Set)) ct.Fields = existingFields @@ -245,7 +245,7 @@ func resourceContentTypeUpdate(d *schema.ResourceData, m interface{}) (err error } func resourceContentTypeDelete(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Contentful) + client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) ct, err := client.ContentTypes.Get(spaceID, d.Id()) diff --git a/resource_contentful_contenttype_test.go b/resource_contentful_contenttype_test.go index cd1fcc5..5900087 100644 --- a/resource_contentful_contenttype_test.go +++ b/resource_contentful_contenttype_test.go @@ -6,7 +6,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" - contentful "github.com/tolgaakyuz/contentful-go" + contentful "github.com/labd/contentful-go" ) func TestAccContentfulContentType_Basic(t *testing.T) { @@ -15,17 +15,17 @@ func TestAccContentfulContentType_Basic(t *testing.T) { Providers: testAccProviders, CheckDestroy: testAccCheckContentfulContentTypeDestroy, Steps: []resource.TestStep{ - resource.TestStep{ + { Config: testAccContentfulContentTypeConfig, Check: resource.TestCheckResourceAttr( "contentful_contenttype.mycontenttype", "name", "TF Acc Test CT 1"), }, - resource.TestStep{ + { Config: testAccContentfulContentTypeUpdateConfig, Check: resource.TestCheckResourceAttr( "contentful_contenttype.mycontenttype", "name", "TF Acc Test CT name change"), }, - resource.TestStep{ + { Config: testAccContentfulContentTypeLinkConfig, Check: resource.TestCheckResourceAttr( "contentful_contenttype.mylinked_contenttype", "name", "TF Acc Test Linked CT"), @@ -38,19 +38,19 @@ func testAccCheckContentfulContentTypeExists(n string, contentType *contentful.C return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] if !ok { - return fmt.Errorf("Not found %s", n) + return fmt.Errorf("not found %s", n) } if rs.Primary.ID == "" { - return fmt.Errorf("No content type ID is set") + return fmt.Errorf("no content type ID is set") } spaceID := rs.Primary.Attributes["space_id"] if spaceID == "" { - return fmt.Errorf("No space_id is set") + return fmt.Errorf("no space_id is set") } - client := testAccProvider.Meta().(*contentful.Contentful) + client := testAccProvider.Meta().(*contentful.Client) ct, err := client.ContentTypes.Get(spaceID, rs.Primary.ID) if err != nil { @@ -71,17 +71,17 @@ func testAccCheckContentfulContentTypeDestroy(s *terraform.State) (err error) { spaceID := rs.Primary.Attributes["space_id"] if spaceID == "" { - return fmt.Errorf("No space_id is set") + return fmt.Errorf("no space_id is set") } - client := testAccProvider.Meta().(*contentful.Contentful) + client := testAccProvider.Meta().(*contentful.Client) _, err := client.ContentTypes.Get(spaceID, rs.Primary.ID) if _, ok := err.(contentful.NotFoundError); ok { return nil } - return fmt.Errorf("Content Type still exists with id: %s", rs.Primary.ID) + return fmt.Errorf("content Type still exists with id: %s", rs.Primary.ID) } return nil diff --git a/resource_contentful_locale.go b/resource_contentful_locale.go index 9983222..1c51b50 100644 --- a/resource_contentful_locale.go +++ b/resource_contentful_locale.go @@ -2,7 +2,7 @@ package main import ( "github.com/hashicorp/terraform/helper/schema" - contentful "github.com/tolgaakyuz/contentful-go" + contentful "github.com/labd/contentful-go" ) func resourceContentfulLocale() *schema.Resource { @@ -13,38 +13,38 @@ func resourceContentfulLocale() *schema.Resource { Delete: resourceDeleteLocale, Schema: map[string]*schema.Schema{ - "version": &schema.Schema{ + "version": { Type: schema.TypeInt, Computed: true, }, - "space_id": &schema.Schema{ + "space_id": { Type: schema.TypeString, Required: true, }, - "name": &schema.Schema{ + "name": { Type: schema.TypeString, Required: true, }, - "code": &schema.Schema{ + "code": { Type: schema.TypeString, Required: true, }, - "fallback_code": &schema.Schema{ + "fallback_code": { Type: schema.TypeString, Optional: true, Default: "en-US", }, - "optional": &schema.Schema{ + "optional": { Type: schema.TypeBool, Optional: true, Default: false, }, - "cda": &schema.Schema{ + "cda": { Type: schema.TypeBool, Optional: true, Default: true, }, - "cma": &schema.Schema{ + "cma": { Type: schema.TypeBool, Optional: true, Default: false, @@ -54,7 +54,7 @@ func resourceContentfulLocale() *schema.Resource { } func resourceCreateLocale(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Contentful) + client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) locale := &contentful.Locale{ @@ -82,7 +82,7 @@ func resourceCreateLocale(d *schema.ResourceData, m interface{}) (err error) { } func resourceReadLocale(d *schema.ResourceData, m interface{}) error { - client := m.(*contentful.Contentful) + client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) localeID := d.Id() @@ -100,7 +100,7 @@ func resourceReadLocale(d *schema.ResourceData, m interface{}) error { } func resourceUpdateLocale(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Contentful) + client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) localeID := d.Id() @@ -130,7 +130,7 @@ func resourceUpdateLocale(d *schema.ResourceData, m interface{}) (err error) { } func resourceDeleteLocale(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Contentful) + client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) localeID := d.Id() diff --git a/resource_contentful_locale_test.go b/resource_contentful_locale_test.go index f6e06aa..b431fe7 100644 --- a/resource_contentful_locale_test.go +++ b/resource_contentful_locale_test.go @@ -7,7 +7,7 @@ import ( "github.com/hashicorp/terraform/helper/acctest" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" - contentful "github.com/tolgaakyuz/contentful-go" + contentful "github.com/labd/contentful-go" ) func TestAccContentfulLocales_Basic(t *testing.T) { @@ -21,7 +21,7 @@ func TestAccContentfulLocales_Basic(t *testing.T) { Providers: testAccProviders, CheckDestroy: testAccContentfulLocaleDestroy, Steps: []resource.TestStep{ - resource.TestStep{ + { Config: testAccContentfulLocaleConfig(spaceName, name), Check: resource.ComposeTestCheckFunc( testAccCheckContentfulLocaleExists("contentful_locale.mylocale", &locale), @@ -35,7 +35,7 @@ func TestAccContentfulLocales_Basic(t *testing.T) { }), ), }, - resource.TestStep{ + { Config: testAccContentfulLocaleUpdateConfig(spaceName, name), Check: resource.ComposeTestCheckFunc( testAccCheckContentfulLocaleExists("contentful_locale.mylocale", &locale), @@ -57,20 +57,20 @@ func testAccCheckContentfulLocaleExists(n string, locale *contentful.Locale) res return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] if !ok { - return fmt.Errorf("Not Found: %s", n) + return fmt.Errorf("not Found: %s", n) } spaceID := rs.Primary.Attributes["space_id"] if spaceID == "" { - return fmt.Errorf("No space_id is set") + return fmt.Errorf("no space_id is set") } localeID := rs.Primary.ID if localeID == "" { - return fmt.Errorf("No locale ID is set") + return fmt.Errorf("no locale ID is set") } - client := testAccProvider.Meta().(*contentful.Contentful) + client := testAccProvider.Meta().(*contentful.Client) contentfulLocale, err := client.Locales.Get(spaceID, localeID) if err != nil { @@ -87,32 +87,32 @@ func testAccCheckContentfulLocaleAttributes(locale *contentful.Locale, attrs map return func(s *terraform.State) error { name := attrs["name"].(string) if locale.Name != name { - return fmt.Errorf("Locale name does not match: %s, %s", locale.Name, name) + return fmt.Errorf("locale name does not match: %s, %s", locale.Name, name) } code := attrs["code"].(string) if locale.Code != code { - return fmt.Errorf("Locale code does not match: %s, %s", locale.Code, code) + return fmt.Errorf("locale code does not match: %s, %s", locale.Code, code) } fallbackCode := attrs["fallback_code"].(string) if locale.FallbackCode != fallbackCode { - return fmt.Errorf("Locale fallback code does not match: %s, %s", locale.FallbackCode, fallbackCode) + return fmt.Errorf("locale fallback code does not match: %s, %s", locale.FallbackCode, fallbackCode) } isOptional := attrs["optional"].(bool) if locale.Optional != isOptional { - return fmt.Errorf("Locale options value does not match: %t, %t", locale.Optional, isOptional) + return fmt.Errorf("locale options value does not match: %t, %t", locale.Optional, isOptional) } isCDA := attrs["cda"].(bool) if locale.CDA != isCDA { - return fmt.Errorf("Locale cda does not match: %t, %t", locale.CDA, isCDA) + return fmt.Errorf("locale cda does not match: %t, %t", locale.CDA, isCDA) } isCMA := attrs["cma"].(bool) if locale.CMA != isCMA { - return fmt.Errorf("Locale cma does not match: %t, %t", locale.CMA, isCMA) + return fmt.Errorf("locale cma does not match: %t, %t", locale.CMA, isCMA) } return nil @@ -127,22 +127,22 @@ func testAccContentfulLocaleDestroy(s *terraform.State) error { spaceID := rs.Primary.Attributes["space_id"] if spaceID == "" { - return fmt.Errorf("No space_id is set") + return fmt.Errorf("no space_id is set") } localeID := rs.Primary.ID if localeID == "" { - return fmt.Errorf("No locale ID is set") + return fmt.Errorf("no locale ID is set") } - client := testAccProvider.Meta().(*contentful.Contentful) + client := testAccProvider.Meta().(*contentful.Client) _, err := client.Locales.Get(spaceID, localeID) if _, ok := err.(contentful.NotFoundError); ok { return nil } - return fmt.Errorf("Locale still exists with id: %s", localeID) + return fmt.Errorf("locale still exists with id: %s", localeID) } return nil diff --git a/resource_contentful_space.go b/resource_contentful_space.go index ee1d4e1..0f7288c 100644 --- a/resource_contentful_space.go +++ b/resource_contentful_space.go @@ -2,7 +2,7 @@ package main import ( "github.com/hashicorp/terraform/helper/schema" - contentful "github.com/tolgaakyuz/contentful-go" + contentful "github.com/labd/contentful-go" ) func resourceContentfulSpace() *schema.Resource { @@ -13,16 +13,16 @@ func resourceContentfulSpace() *schema.Resource { Delete: resourceSpaceDelete, Schema: map[string]*schema.Schema{ - "version": &schema.Schema{ + "version": { Type: schema.TypeInt, Computed: true, }, - "name": &schema.Schema{ + "name": { Type: schema.TypeString, Required: true, }, // Space specific props - "default_locale": &schema.Schema{ + "default_locale": { Type: schema.TypeString, Optional: true, Default: "en", @@ -32,7 +32,7 @@ func resourceContentfulSpace() *schema.Resource { } func resourceSpaceCreate(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Contentful) + client := m.(*contentful.Client) space := &contentful.Space{ Name: d.Get("name").(string), @@ -55,7 +55,7 @@ func resourceSpaceCreate(d *schema.ResourceData, m interface{}) (err error) { } func resourceSpaceRead(d *schema.ResourceData, m interface{}) error { - client := m.(*contentful.Contentful) + client := m.(*contentful.Client) spaceID := d.Id() _, err := client.Spaces.Get(spaceID) @@ -68,7 +68,7 @@ func resourceSpaceRead(d *schema.ResourceData, m interface{}) error { } func resourceSpaceUpdate(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Contentful) + client := m.(*contentful.Client) spaceID := d.Id() space, err := client.Spaces.Get(spaceID) @@ -87,7 +87,7 @@ func resourceSpaceUpdate(d *schema.ResourceData, m interface{}) (err error) { } func resourceSpaceDelete(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Contentful) + client := m.(*contentful.Client) spaceID := d.Id() space, err := client.Spaces.Get(spaceID) diff --git a/resource_contentful_space_test.go b/resource_contentful_space_test.go index da1e9e5..df2bdba 100644 --- a/resource_contentful_space_test.go +++ b/resource_contentful_space_test.go @@ -6,7 +6,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" - contentful "github.com/tolgaakyuz/contentful-go" + contentful "github.com/labd/contentful-go" ) func TestAccContentfulSpace_Basic(t *testing.T) { @@ -16,12 +16,12 @@ func TestAccContentfulSpace_Basic(t *testing.T) { Providers: testAccProviders, CheckDestroy: testAccCheckContentfulSpaceDestroy, Steps: []resource.TestStep{ - resource.TestStep{ + { Config: testAccContentfulSpaceConfig, Check: resource.TestCheckResourceAttr( "contentful_space.myspace", "name", "TF Acc Test Space"), }, - resource.TestStep{ + { Config: testAccContentfulSpaceUpdateConfig, Check: resource.TestCheckResourceAttr( "contentful_space.myspace", "name", "TF Acc Test Changed Space"), @@ -31,7 +31,7 @@ func TestAccContentfulSpace_Basic(t *testing.T) { } func testAccCheckContentfulSpaceDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*contentful.Contentful) + client := testAccProvider.Meta().(*contentful.Client) for _, rs := range s.RootModule().Resources { if rs.Type != "contentful_space" { @@ -40,7 +40,7 @@ func testAccCheckContentfulSpaceDestroy(s *terraform.State) error { space, err := client.Spaces.Get(rs.Primary.ID) if err == nil { - return fmt.Errorf("Space %s still exists after destroy", space.Sys.ID) + return fmt.Errorf("space %s still exists after destroy", space.Sys.ID) } } diff --git a/resource_contentful_webhook.go b/resource_contentful_webhook.go index e7830bd..60f338a 100644 --- a/resource_contentful_webhook.go +++ b/resource_contentful_webhook.go @@ -2,7 +2,7 @@ package main import ( "github.com/hashicorp/terraform/helper/schema" - contentful "github.com/tolgaakyuz/contentful-go" + contentful "github.com/labd/contentful-go" ) func resourceContentfulWebhook() *schema.Resource { @@ -13,38 +13,38 @@ func resourceContentfulWebhook() *schema.Resource { Delete: resourceDeleteWebhook, Schema: map[string]*schema.Schema{ - "version": &schema.Schema{ + "version": { Type: schema.TypeInt, Computed: true, }, - "space_id": &schema.Schema{ + "space_id": { Type: schema.TypeString, Required: true, }, - "name": &schema.Schema{ + "name": { Type: schema.TypeString, Required: true, }, // Webhook specific props - "url": &schema.Schema{ + "url": { Type: schema.TypeString, Required: true, }, - "http_basic_auth_username": &schema.Schema{ + "http_basic_auth_username": { Type: schema.TypeString, Optional: true, Default: "", }, - "http_basic_auth_password": &schema.Schema{ + "http_basic_auth_password": { Type: schema.TypeString, Optional: true, Default: "", }, - "headers": &schema.Schema{ + "headers": { Type: schema.TypeMap, Optional: true, }, - "topics": &schema.Schema{ + "topics": { Type: schema.TypeList, Elem: &schema.Schema{ Type: schema.TypeString, @@ -57,7 +57,7 @@ func resourceContentfulWebhook() *schema.Resource { } func resourceCreateWebhook(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Contentful) + client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) webhook := &contentful.Webhook{ @@ -85,7 +85,7 @@ func resourceCreateWebhook(d *schema.ResourceData, m interface{}) (err error) { } func resourceUpdateWebhook(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Contentful) + client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) webhookID := d.Id() @@ -117,7 +117,7 @@ func resourceUpdateWebhook(d *schema.ResourceData, m interface{}) (err error) { } func resourceReadWebhook(d *schema.ResourceData, m interface{}) error { - client := m.(*contentful.Contentful) + client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) webhookID := d.Id() @@ -135,7 +135,7 @@ func resourceReadWebhook(d *schema.ResourceData, m interface{}) error { } func resourceDeleteWebhook(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Contentful) + client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) webhookID := d.Id() @@ -197,7 +197,7 @@ func setWebhookProperties(d *schema.ResourceData, webhook *contentful.Webhook) ( } func transformHeadersToContentfulFormat(headersTerraform interface{}) []*contentful.WebhookHeader { - headers := []*contentful.WebhookHeader{} + var headers []*contentful.WebhookHeader for k, v := range headersTerraform.(map[string]interface{}) { headers = append(headers, &contentful.WebhookHeader{ diff --git a/resource_contentful_webhook_test.go b/resource_contentful_webhook_test.go index c35e59f..a4a6bb3 100644 --- a/resource_contentful_webhook_test.go +++ b/resource_contentful_webhook_test.go @@ -6,7 +6,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" - contentful "github.com/tolgaakyuz/contentful-go" + contentful "github.com/labd/contentful-go" ) func TestAccContentfulWebhook_Basic(t *testing.T) { @@ -17,24 +17,24 @@ func TestAccContentfulWebhook_Basic(t *testing.T) { Providers: testAccProviders, CheckDestroy: testAccContentfulWebhookDestroy, Steps: []resource.TestStep{ - resource.TestStep{ + { Config: testAccContentfulWebhookConfig, Check: resource.ComposeTestCheckFunc( testAccCheckContentfulWebhookExists("contentful_webhook.mywebhook", &webhook), testAccCheckContentfulWebhookAttributes(&webhook, map[string]interface{}{ - "name": "webhook-name", - "url": "https://www.example.com/test", + "name": "webhook-name", + "url": "https://www.example.com/test", "http_basic_auth_username": "username", }), ), }, - resource.TestStep{ + { Config: testAccContentfulWebhookUpdateConfig, Check: resource.ComposeTestCheckFunc( testAccCheckContentfulWebhookExists("contentful_webhook.mywebhook", &webhook), testAccCheckContentfulWebhookAttributes(&webhook, map[string]interface{}{ - "name": "webhook-name-updated", - "url": "https://www.example.com/test-updated", + "name": "webhook-name-updated", + "url": "https://www.example.com/test-updated", "http_basic_auth_username": "username-updated", }), ), @@ -47,21 +47,21 @@ func testAccCheckContentfulWebhookExists(n string, webhook *contentful.Webhook) return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] if !ok { - return fmt.Errorf("Not Found: %s", n) + return fmt.Errorf("not Found: %s", n) } // get space id from resource data spaceID := rs.Primary.Attributes["space_id"] if spaceID == "" { - return fmt.Errorf("No space_id is set") + return fmt.Errorf("no space_id is set") } // check webhook resource id if rs.Primary.ID == "" { - return fmt.Errorf("No webhook ID is set") + return fmt.Errorf("no webhook ID is set") } - client := testAccProvider.Meta().(*contentful.Contentful) + client := testAccProvider.Meta().(*contentful.Client) contentfulWebhook, err := client.Webhooks.Get(spaceID, rs.Primary.ID) if err != nil { @@ -78,12 +78,12 @@ func testAccCheckContentfulWebhookAttributes(webhook *contentful.Webhook, attrs return func(s *terraform.State) error { name := attrs["name"].(string) if webhook.Name != name { - return fmt.Errorf("Webhook name does not match: %s, %s", webhook.Name, name) + return fmt.Errorf("webhook name does not match: %s, %s", webhook.Name, name) } url := attrs["url"].(string) if webhook.URL != url { - return fmt.Errorf("Webhook url does not match: %s, %s", webhook.URL, url) + return fmt.Errorf("webhook url does not match: %s, %s", webhook.URL, url) } /* topics := attrs["topics"].([]string) @@ -92,7 +92,7 @@ func testAccCheckContentfulWebhookAttributes(webhook *contentful.Webhook, attrs httpBasicAuthUsername := attrs["http_basic_auth_username"].(string) if webhook.HTTPBasicUsername != httpBasicAuthUsername { - return fmt.Errorf("Webhook http_basic_auth_username does not match: %s, %s", webhook.HTTPBasicUsername, httpBasicAuthUsername) + return fmt.Errorf("webhook http_basic_auth_username does not match: %s, %s", webhook.HTTPBasicUsername, httpBasicAuthUsername) } return nil @@ -108,23 +108,23 @@ func testAccContentfulWebhookDestroy(s *terraform.State) error { // get space id from resource data spaceID := rs.Primary.Attributes["space_id"] if spaceID == "" { - return fmt.Errorf("No space_id is set") + return fmt.Errorf("no space_id is set") } // check webhook resource id if rs.Primary.ID == "" { - return fmt.Errorf("No webhook ID is set") + return fmt.Errorf("no webhook ID is set") } // sdk client - client := testAccProvider.Meta().(*contentful.Contentful) + client := testAccProvider.Meta().(*contentful.Client) _, err := client.Webhooks.Get(spaceID, rs.Primary.ID) if _, ok := err.(contentful.NotFoundError); ok { return nil } - return fmt.Errorf("Webhook still exists with id: %s", rs.Primary.ID) + return fmt.Errorf("webhook still exists with id: %s", rs.Primary.ID) } return nil From 9592d2090e4369ebe4c82c6158c1cfac9e8b5345 Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Wed, 15 Apr 2020 17:05:16 +0200 Subject: [PATCH 041/192] Fixed non working code and some test related bugs. The unit tests no longer create a space themselves. This because most Contentful users do not have the rights to create spaces in their organization, so automatically creating a space would result in a FAIL. --- resource_contentful_apikey.go | 8 + resource_contentful_apikey_test.go | 41 +-- resource_contentful_contenttype.go | 447 ++++++++++++++++++++++-- resource_contentful_contenttype_test.go | 125 +++---- resource_contentful_locale_test.go | 42 +-- resource_contentful_space_test.go | 1 - 6 files changed, 520 insertions(+), 144 deletions(-) diff --git a/resource_contentful_apikey.go b/resource_contentful_apikey.go index 7d3b787..2de94d7 100644 --- a/resource_contentful_apikey.go +++ b/resource_contentful_apikey.go @@ -17,6 +17,10 @@ func resourceContentfulAPIKey() *schema.Resource { Type: schema.TypeInt, Computed: true, }, + "access_token": { + Type: schema.TypeString, + Computed: true, + }, "space_id": { Type: schema.TypeString, Required: true, @@ -126,5 +130,9 @@ func setAPIKeyProperties(d *schema.ResourceData, apiKey *contentful.APIKey) erro return err } + if err := d.Set("access_token", apiKey.AccessToken); err != nil { + return err + } + return nil } diff --git a/resource_contentful_apikey_test.go b/resource_contentful_apikey_test.go index 5531c69..2b76185 100644 --- a/resource_contentful_apikey_test.go +++ b/resource_contentful_apikey_test.go @@ -13,7 +13,6 @@ import ( func TestAccContentfulAPIKey_Basic(t *testing.T) { var apiKey contentful.APIKey - spaceName := fmt.Sprintf("space-name-%s", acctest.RandString(3)) name := fmt.Sprintf("apikey-name-%s", acctest.RandString(3)) description := fmt.Sprintf("apikey-description-%s", acctest.RandString(3)) @@ -22,8 +21,8 @@ func TestAccContentfulAPIKey_Basic(t *testing.T) { Providers: testAccProviders, CheckDestroy: testAccContentfulAPIKeyDestroy, Steps: []resource.TestStep{ - resource.TestStep{ - Config: testAccContentfulAPIKeyConfig(spaceName, name, description), + { + Config: testAccContentfulAPIKeyConfig(name, description), Check: resource.ComposeTestCheckFunc( testAccCheckContentfulAPIKeyExists("contentful_apikey.myapikey", &apiKey), testAccCheckContentfulAPIKeyAttributes(&apiKey, map[string]interface{}{ @@ -32,8 +31,8 @@ func TestAccContentfulAPIKey_Basic(t *testing.T) { }), ), }, - resource.TestStep{ - Config: testAccContentfulAPIKeyUpdateConfig(spaceName, name, description), + { + Config: testAccContentfulAPIKeyUpdateConfig(name, description), Check: resource.ComposeTestCheckFunc( testAccCheckContentfulAPIKeyExists("contentful_apikey.myapikey", &apiKey), testAccCheckContentfulAPIKeyAttributes(&apiKey, map[string]interface{}{ @@ -50,17 +49,17 @@ func testAccCheckContentfulAPIKeyExists(n string, apiKey *contentful.APIKey) res return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] if !ok { - return fmt.Errorf("Not Found: %s", n) + return fmt.Errorf("not Found: %s", n) } spaceID := rs.Primary.Attributes["space_id"] if spaceID == "" { - return fmt.Errorf("No space_id is set") + return fmt.Errorf("no space_id is set") } apiKeyID := rs.Primary.ID if apiKeyID == "" { - return fmt.Errorf("No api key ID is set") + return fmt.Errorf("no api key ID is set") } client := testAccProvider.Meta().(*contentful.Client) @@ -101,12 +100,12 @@ func testAccContentfulAPIKeyDestroy(s *terraform.State) error { // get space id from resource data spaceID := rs.Primary.Attributes["space_id"] if spaceID == "" { - return fmt.Errorf("No space_id is set") + return fmt.Errorf("no space_id is set") } apiKeyID := rs.Primary.ID if apiKeyID == "" { - return fmt.Errorf("No apikey ID is set") + return fmt.Errorf("no apikey ID is set") } client := testAccProvider.Meta().(*contentful.Client) @@ -116,38 +115,30 @@ func testAccContentfulAPIKeyDestroy(s *terraform.State) error { return nil } - return fmt.Errorf("Api Key still exists with id: %s", rs.Primary.ID) + return fmt.Errorf("api Key still exists with id: %s", rs.Primary.ID) } return nil } -func testAccContentfulAPIKeyConfig(spaceName, name, description string) string { +func testAccContentfulAPIKeyConfig(name, description string) string { return fmt.Sprintf(` -resource "contentful_space" "myspace" { - name = "%s" -} - resource "contentful_apikey" "myapikey" { - space_id = "${contentful_space.myspace.id}" + space_id = "uhwvl4veejyj" name = "%s" description = "%s" } -`, spaceName, name, description) +`, name, description) } -func testAccContentfulAPIKeyUpdateConfig(spaceName, name, description string) string { +func testAccContentfulAPIKeyUpdateConfig(name, description string) string { return fmt.Sprintf(` -resource "contentful_space" "myspace" { - name = "%s" -} - resource "contentful_apikey" "myapikey" { - space_id = "${contentful_space.myspace.id}" + space_id = "uhwvl4veejyj" name = "%s-updated" description = "%s-updated" } -`, spaceName, name, description) +`, name, description) } diff --git a/resource_contentful_contenttype.go b/resource_contentful_contenttype.go index b261ba7..116932e 100644 --- a/resource_contentful_contenttype.go +++ b/resource_contentful_contenttype.go @@ -3,6 +3,7 @@ package main import ( "github.com/hashicorp/terraform/helper/schema" contentful "github.com/labd/contentful-go" + "time" ) func resourceContentfulContentType() *schema.Resource { @@ -35,9 +36,8 @@ func resourceContentfulContentType() *schema.Resource { Required: true, }, "field": { - Type: schema.TypeSet, + Type: schema.TypeList, Required: true, - MinItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "id": { @@ -48,7 +48,6 @@ func resourceContentfulContentType() *schema.Resource { Type: schema.TypeString, Required: true, }, - //@TODO Add ValidateFunc to validate field type "type": { Type: schema.TypeString, Required: true, @@ -58,7 +57,7 @@ func resourceContentfulContentType() *schema.Resource { Optional: true, }, "items": { - Type: schema.TypeSet, + Type: schema.TypeList, Optional: true, MaxItems: 1, Elem: &schema.Resource{ @@ -67,15 +66,15 @@ func resourceContentfulContentType() *schema.Resource { Type: schema.TypeString, Required: true, }, - "validations": { - Type: schema.TypeList, - Optional: true, - Elem: &schema.Schema{Type: schema.TypeString}, - }, "link_type": { Type: schema.TypeString, Required: true, }, + "validation": { + Type: schema.TypeList, + Optional: true, + Elem: generateValidationSchema(), + }, }, }, }, @@ -99,10 +98,10 @@ func resourceContentfulContentType() *schema.Resource { Optional: true, Default: false, }, - "validations": { + "validation": { Type: schema.TypeList, Optional: true, - Elem: &schema.Schema{Type: schema.TypeString}, + Elem: generateValidationSchema(), }, }, }, @@ -125,8 +124,9 @@ func resourceContentTypeCreate(d *schema.ResourceData, m interface{}) (err error ct.Description = description.(string) } - for _, rawField := range d.Get("field").(*schema.Set).List() { - field := rawField.(map[string]interface{}) + rawField := d.Get("field").([]interface{}) + for i := 0; i < len(rawField); i++ { + field := rawField[i].(map[string]interface{}) contentfulField := &contentful.Field{ ID: field["id"].(string), @@ -151,7 +151,7 @@ func resourceContentTypeCreate(d *schema.ResourceData, m interface{}) (err error contentfulField.Validations = parsedValidations } - if items := processItems(field["items"].(*schema.Set)); items != nil { + if items := processItems(field["items"].([]interface{})); items != nil { contentfulField.Items = items } @@ -163,7 +163,6 @@ func resourceContentTypeCreate(d *schema.ResourceData, m interface{}) (err error } if err = client.ContentTypes.Activate(spaceID, ct); err != nil { - //@TODO Maybe delete the CT ? return err } @@ -207,7 +206,7 @@ func resourceContentTypeUpdate(d *schema.ResourceData, m interface{}) (err error if d.HasChange("field") { old, nw := d.GetChange("field") - existingFields, deletedFields = checkFieldChanges(old.(*schema.Set), nw.(*schema.Set)) + existingFields, deletedFields = checkFieldChanges(old.([]interface{}), nw.([]interface{})) ct.Fields = existingFields @@ -224,7 +223,6 @@ func resourceContentTypeUpdate(d *schema.ResourceData, m interface{}) (err error } if err = client.ContentTypes.Activate(spaceID, ct); err != nil { - //@TODO Maybe delete the CT ? return err } @@ -236,7 +234,6 @@ func resourceContentTypeUpdate(d *schema.ResourceData, m interface{}) (err error } if err = client.ContentTypes.Activate(spaceID, ct); err != nil { - //@TODO Maybe delete the CT ? return err } } @@ -274,18 +271,18 @@ func setContentTypeProperties(d *schema.ResourceData, ct *contentful.ContentType return nil } -func checkFieldChanges(old, new *schema.Set) ([]*contentful.Field, []*contentful.Field) { +func checkFieldChanges(old, new []interface{}) ([]*contentful.Field, []*contentful.Field) { var contentfulField *contentful.Field var existingFields []*contentful.Field var deletedFields []*contentful.Field var fieldRemoved bool - for _, f := range old.List() { - oldField := f.(map[string]interface{}) + for i := 0; i < len(old); i++ { + oldField := old[i].(map[string]interface{}) fieldRemoved = true - for _, newField := range new.List() { - if oldField["id"].(string) == newField.(map[string]interface{})["id"].(string) { + for j := 0; j < len(new); j++ { + if oldField["id"].(string) == new[j].(map[string]interface{})["id"].(string) { fieldRemoved = false break } @@ -306,8 +303,8 @@ func checkFieldChanges(old, new *schema.Set) ([]*contentful.Field, []*contentful } } - for _, f := range new.List() { - newField := f.(map[string]interface{}) + for k := 0; k < len(new); k++ { + newField := new[k].(map[string]interface{}) contentfulField = &contentful.Field{ ID: newField["id"].(string), @@ -329,7 +326,7 @@ func checkFieldChanges(old, new *schema.Set) ([]*contentful.Field, []*contentful contentfulField.Validations = parsedValidations } - if items := processItems(newField["items"].(*schema.Set)); items != nil { + if items := processItems(newField["items"].([]interface{})); items != nil { contentfulField.Items = items } @@ -339,11 +336,11 @@ func checkFieldChanges(old, new *schema.Set) ([]*contentful.Field, []*contentful return existingFields, deletedFields } -func processItems(fieldItems *schema.Set) *contentful.FieldTypeArrayItem { +func processItems(fieldItems []interface{}) *contentful.FieldTypeArrayItem { var items *contentful.FieldTypeArrayItem - for _, i := range fieldItems.List() { - item := i.(map[string]interface{}) + for i := 0; i < len(fieldItems); i++ { + item := fieldItems[i].(map[string]interface{}) var validations []contentful.FieldValidation @@ -359,3 +356,395 @@ func processItems(fieldItems *schema.Set) *contentful.FieldTypeArrayItem { } return items } + +// Expanders +// noinspection GoUnusedFunction +func expandContentTypeField(in interface{}) *contentful.Field { + field := &contentful.Field{} + m := in.(map[string]interface{}) + if v, ok := m["id"].(string); ok { + field.ID = v + } + if v, ok := m["name"].(string); ok { + field.Name = v + } + if v, ok := m["type"].(string); ok { + field.Type = v + } + if v, ok := m["link_type"].(string); ok { + field.LinkType = v + } + if v, ok := m["required"].(bool); ok { + field.Required = v + } + if v, ok := m["localized"].(bool); ok { + field.Localized = v + } + if v, ok := m["disabled"].(bool); ok { + field.Disabled = v + } + if v, ok := m["omitted"].(bool); ok { + field.Omitted = v + } + if v, ok := m["validation"].([]interface{}); ok && len(v) > 0 { + validations := make([]contentful.FieldValidation, len(v)) + for i, val := range v { + validations[i] = expandContentTypeFieldValidation(val) + } + field.Validations = validations + } + return field +} + +func expandContentTypeFieldValidation(in interface{}) contentful.FieldValidation { + m := in.(map[string]interface{}) + if v, ok := m["link"].([]string); ok { + return contentful.FieldValidationLink{ + LinkContentType: v, + } + } + if v, ok := m["mime_type"].([]string); ok { + return contentful.FieldValidationMimeType{ + MimeTypes: v, + } + } + if v, ok := m["dimension"].([]interface{}); ok { + return expandContentTypeFieldValidationDimension(v) + } + if v, ok := m["size"].([]interface{}); ok { + return expandContentTypeFieldValidationSize(v) + } + if v, ok := m["file_size"].([]interface{}); ok { + return expandContentTypeFieldValidationFileSize(v) + } + if v, ok := m["unique"].(bool); ok { + return contentful.FieldValidationUnique{ + Unique: v, + } + } + if v, ok := m["range"].([]interface{}); ok { + return expandContentTypeFieldValidationRange(v) + } + if v, ok := m["date"].([]interface{}); ok { + return expandContentTypeFieldValidationDate(v) + } + return nil +} + +func expandContentTypeFieldValidationDimension(in []interface{}) contentful.FieldValidation { + if len(in) == 0 || in[0] == nil { + return contentful.FieldValidationDimension{} + } + + validation := contentful.FieldValidationDimension{} + m := in[0].(map[string]interface{}) + if v, ok := m["min_width"].(float64); ok { + if validation.Width == nil { + validation.Width = &contentful.MinMax{} + } + validation.Width.Min = v + } + if v, ok := m["max_width"].(float64); ok { + if validation.Width == nil { + validation.Width = &contentful.MinMax{} + } + validation.Width.Max = v + } + if v, ok := m["min_height"].(float64); ok { + if validation.Height == nil { + validation.Width = &contentful.MinMax{} + } + validation.Height.Min = v + } + if v, ok := m["max_height"].(float64); ok { + if validation.Height == nil { + validation.Width = &contentful.MinMax{} + } + validation.Height.Max = v + } + if v, ok := m["err_message"].(string); ok { + validation.ErrorMessage = v + } + return validation +} + +func expandContentTypeFieldValidationSize(in []interface{}) contentful.FieldValidation { + if len(in) == 0 || in[0] == nil { + return contentful.FieldValidationSize{} + } + + validation := contentful.FieldValidationSize{} + m := in[0].(map[string]interface{}) + if v, ok := m["min"].(float64); ok { + if validation.Size == nil { + validation.Size = &contentful.MinMax{} + } + validation.Size.Min = v + } + if v, ok := m["max"].(float64); ok { + if validation.Size == nil { + validation.Size = &contentful.MinMax{} + } + validation.Size.Max = v + } + if v, ok := m["err_message"].(string); ok { + validation.ErrorMessage = v + } + return validation +} + +func expandContentTypeFieldValidationFileSize(in []interface{}) contentful.FieldValidation { + if len(in) == 0 || in[0] == nil { + return contentful.FieldValidationFileSize{} + } + + validation := contentful.FieldValidationFileSize{} + m := in[0].(map[string]interface{}) + if v, ok := m["min"].(float64); ok { + if validation.Size == nil { + validation.Size = &contentful.MinMax{} + } + validation.Size.Min = v + } + if v, ok := m["max"].(float64); ok { + if validation.Size == nil { + validation.Size = &contentful.MinMax{} + } + validation.Size.Max = v + } + if v, ok := m["err_message"].(string); ok { + validation.ErrorMessage = v + } + return validation +} + +func expandContentTypeFieldValidationRange(in []interface{}) contentful.FieldValidation { + if len(in) == 0 || in[0] == nil { + return contentful.FieldValidationRange{} + } + + validation := contentful.FieldValidationRange{} + m := in[0].(map[string]interface{}) + if v, ok := m["min"].(float64); ok { + if validation.Range == nil { + validation.Range = &contentful.MinMax{} + } + validation.Range.Min = v + } + if v, ok := m["max"].(float64); ok { + if validation.Range == nil { + validation.Range = &contentful.MinMax{} + } + validation.Range.Max = v + } + if v, ok := m["err_message"].(string); ok { + validation.ErrorMessage = v + } + return validation +} + +func expandContentTypeFieldValidationDate(in []interface{}) contentful.FieldValidation { + if len(in) == 0 || in[0] == nil { + return contentful.FieldValidationDate{} + } + + validation := contentful.FieldValidationDate{} + m := in[0].(map[string]interface{}) + if v, ok := m["min"].(time.Time); ok { + if validation.Range == nil { + validation.Range = &contentful.DateMinMax{} + } + validation.Range.Min = v + } + if v, ok := m["max"].(time.Time); ok { + if validation.Range == nil { + validation.Range = &contentful.DateMinMax{} + } + validation.Range.Max = v + } + if v, ok := m["err_message"].(string); ok { + validation.ErrorMessage = v + } + return validation +} + +// noinspection GoUnusedFunction +func expandContentTypeFieldValidationRegex(in []interface{}) contentful.FieldValidation { + if len(in) == 0 || in[0] == nil { + return contentful.FieldValidationRegex{} + } + + validation := contentful.FieldValidationRegex{} + m := in[0].(map[string]interface{}) + if v, ok := m["pattern"].(string); ok { + if validation.Regex == nil { + validation.Regex = &contentful.Regex{} + } + validation.Regex.Pattern = v + } + if v, ok := m["flags"].(string); ok { + if validation.Regex == nil { + validation.Regex = &contentful.Regex{} + } + validation.Regex.Flags = v + } + if v, ok := m["err_message"].(string); ok { + validation.ErrorMessage = v + } + return validation +} + +func generateValidationSchema() *schema.Resource { + return &schema.Resource{ + Schema: map[string]*schema.Schema{ + "link": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "mime_type": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "dimension": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "min_width": { + Type: schema.TypeFloat, + Required: true, + }, + "max_width": { + Type: schema.TypeFloat, + Required: true, + }, + "min_height": { + Type: schema.TypeFloat, + Required: true, + }, + "max_height": { + Type: schema.TypeFloat, + Required: true, + }, + "err_message": { + Type: schema.TypeString, + Required: true, + }, + }, + }, + }, + "size": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "min": { + Type: schema.TypeFloat, + Optional: true, + }, + "max": { + Type: schema.TypeFloat, + Optional: true, + }, + "err_message": { + Type: schema.TypeString, + Optional: true, + }, + }, + }, + }, + "file_size": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "min": { + Type: schema.TypeFloat, + Optional: true, + }, + "max": { + Type: schema.TypeFloat, + Optional: true, + }, + "err_message": { + Type: schema.TypeString, + Optional: true, + }, + }, + }, + }, + "unique": { + Type: schema.TypeBool, + Optional: true, + }, + "range": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "min": { + Type: schema.TypeFloat, + Optional: true, + }, + "max": { + Type: schema.TypeFloat, + Optional: true, + }, + "err_message": { + Type: schema.TypeString, + Optional: true, + }, + }, + }, + }, + "date": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "min": { + Type: schema.TypeString, + Optional: true, + }, + "max": { + Type: schema.TypeString, + Optional: true, + }, + "err_message": { + Type: schema.TypeString, + Optional: true, + }, + }, + }, + }, + "regex": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "pattern": { + Type: schema.TypeString, + Optional: true, + }, + "flags": { + Type: schema.TypeString, + Optional: true, + }, + "err_message": { + Type: schema.TypeString, + Optional: true, + }, + }, + }, + }, + }, + } +} diff --git a/resource_contentful_contenttype_test.go b/resource_contentful_contenttype_test.go index 5900087..fa1afdb 100644 --- a/resource_contentful_contenttype_test.go +++ b/resource_contentful_contenttype_test.go @@ -34,6 +34,7 @@ func TestAccContentfulContentType_Basic(t *testing.T) { }) } +// noinspection GoUnusedFunction func testAccCheckContentfulContentTypeExists(n string, contentType *contentful.ContentType) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] @@ -81,113 +82,119 @@ func testAccCheckContentfulContentTypeDestroy(s *terraform.State) (err error) { return nil } - return fmt.Errorf("content Type still exists with id: %s", rs.Primary.ID) + return fmt.Errorf("content type still exists with id: %s", rs.Primary.ID) } return nil } var testAccContentfulContentTypeConfig = ` -// resource "contentful_space" "myspace" { -// name = "TF Acc Test Space" -// } - resource "contentful_contenttype" "mycontenttype" { - space_id = "${contentful_space.myspace.id}" - + space_id = "uhwvl4veejyj" name = "TF Acc Test CT 1" description = "Terraform Acc Test Content Type" display_field = "field1" - field { - id = "field1" - name = "Field 1" - type = "Text" - required = true + disabled = false + id = "field1" + localized = false + name = "Field 1" + omitted = false + required = true + type = "Text" } - field { - id = "field2" - name = "Field 2" - type = "Integer" - required = false + disabled = false + id = "field2" + localized = false + name = "Field 2" + omitted = false + required = true + type = "Integer" } } ` var testAccContentfulContentTypeUpdateConfig = ` resource "contentful_contenttype" "mycontenttype" { - space_id = "${contentful_space.myspace.id}" - + space_id = "uhwvl4veejyj" name = "TF Acc Test CT name change" description = "Terraform Acc Test Content Type description change" display_field = "field1" - field { - id = "field1" - name = "Field 1 name change" - type = "Text" - required = true + disabled = false + id = "field1" + localized = false + name = "Field 1 name change" + omitted = false + required = true + type = "Text" } - field { - id = "field3" - name = "Field 3 new field" - type = "Integer" - required = true + disabled = false + id = "field3" + localized = false + name = "Field 3 new field" + omitted = false + required = true + type = "Integer" } } ` + var testAccContentfulContentTypeLinkConfig = ` resource "contentful_contenttype" "mycontenttype" { - space_id = "${contentful_space.myspace.id}" - + space_id = "uhwvl4veejyj" name = "TF Acc Test CT name change" description = "Terraform Acc Test Content Type description change" display_field = "field1" - field { - id = "field1" - name = "Field 1 name change" - type = "Text" - required = true + disabled = false + id = "field1" + localized = false + name = "Field 1 name change" + omitted = false + required = true + type = "Text" } - field { - id = "field3" - name = "Field 3 new field" - type = "Integer" - required = true + disabled = false + id = "field3" + localized = false + name = "Field 3 new field" + omitted = false + required = true + type = "Integer" } } resource "contentful_contenttype" "mylinked_contenttype" { - space_id = "${contentful_space.myspace.id}" - - name = "TF Acc Test Linked CT" - description = "Terraform Acc Test Content Type with links" + space_id = "uhwvl4veejyj" + name = "TF Acc Test Linked CT" + description = "Terraform Acc Test Content Type with links" display_field = "asset_field" - field { - id = "asset_field" + id = "asset_field" name = "Asset Field" type = "Array" - items { - type = "Link" - link_type = "Asset" - } + items { + type = "Link" + link_type = "Asset" + } required = true } - field { - id = "entry_link_field" - name = "Entry Link Field" - type = "Link" - link_type = "Entry" - validations = ["{\"linkContentType\": [\"${contentful_contenttype.mycontenttype.id}\"]}"] + id = "entry_link_field" + name = "Entry Link Field" + type = "Link" + link_type = "Entry" + dynamic "validation" { + for_each = ["{\"linkContentType\": [\"${contentful_contenttype.mycontenttype.id}\"]}"] + content { + link = lookup(contentful_contenttype.mycontenttype, "link", null) + } + } required = false } - } - ` diff --git a/resource_contentful_locale_test.go b/resource_contentful_locale_test.go index b431fe7..b4ba1b6 100644 --- a/resource_contentful_locale_test.go +++ b/resource_contentful_locale_test.go @@ -4,7 +4,6 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform/helper/acctest" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" contentful "github.com/labd/contentful-go" @@ -13,20 +12,17 @@ import ( func TestAccContentfulLocales_Basic(t *testing.T) { var locale contentful.Locale - spaceName := fmt.Sprintf("space-name-%s", acctest.RandString(3)) - name := fmt.Sprintf("locale-name-%s", acctest.RandString(3)) - resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, CheckDestroy: testAccContentfulLocaleDestroy, Steps: []resource.TestStep{ { - Config: testAccContentfulLocaleConfig(spaceName, name), + Config: testAccContentfulLocaleConfig, Check: resource.ComposeTestCheckFunc( testAccCheckContentfulLocaleExists("contentful_locale.mylocale", &locale), testAccCheckContentfulLocaleAttributes(&locale, map[string]interface{}{ - "name": name, + "name": "locale-name", "code": "de", "fallback_code": "en-US", "optional": false, @@ -36,11 +32,11 @@ func TestAccContentfulLocales_Basic(t *testing.T) { ), }, { - Config: testAccContentfulLocaleUpdateConfig(spaceName, name), + Config: testAccContentfulLocaleUpdateConfig, Check: resource.ComposeTestCheckFunc( testAccCheckContentfulLocaleExists("contentful_locale.mylocale", &locale), testAccCheckContentfulLocaleAttributes(&locale, map[string]interface{}{ - "name": fmt.Sprintf("%s-updated", name), + "name": "locale-name-updated", "code": "es", "fallback_code": "en-US", "optional": true, @@ -148,42 +144,28 @@ func testAccContentfulLocaleDestroy(s *terraform.State) error { return nil } -func testAccContentfulLocaleConfig(spaceName, name string) string { - return fmt.Sprintf(` -resource "contentful_space" "myspace" { - name = "%s" - default_locale = "en-US" -} - +var testAccContentfulLocaleConfig = ` resource "contentful_locale" "mylocale" { - space_id = "${contentful_space.myspace.id}" + space_id = "uhwvl4veejyj" - name = "%s" + name = "locale-name" code = "de" fallback_code = "en-US" optional = false cda = false cma = true } -`, spaceName, name) -} - -func testAccContentfulLocaleUpdateConfig(spaceName, name string) string { - return fmt.Sprintf(` -resource "contentful_space" "myspace" { - name = "%s" - default_locale = "en-US" -} +` +var testAccContentfulLocaleUpdateConfig = ` resource "contentful_locale" "mylocale" { - space_id = "${contentful_space.myspace.id}" + space_id = "uhwvl4veejyj" - name = "%s-updated" + name = "locale-name-updated" code = "es" fallback_code = "en-US" optional = true cda = true cma = false } -`, spaceName, name) -} +` diff --git a/resource_contentful_space_test.go b/resource_contentful_space_test.go index df2bdba..f52b856 100644 --- a/resource_contentful_space_test.go +++ b/resource_contentful_space_test.go @@ -10,7 +10,6 @@ import ( ) func TestAccContentfulSpace_Basic(t *testing.T) { - t.Skip() resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, From c47c04b6b691d61f4a14c1c75dbf3bf064ad22ae Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Thu, 16 Apr 2020 10:05:09 +0200 Subject: [PATCH 042/192] Correct project setup Fixed the setup of the project files, and edited the makefile to accept the usual commands. --- .gitignore | 17 ++++++++ Dockerfile-test | 11 ------ Makefile | 39 ++++++------------- circle.yml | 15 ------- constants.go => contentful/constants.go | 2 +- provider.go => contentful/provider.go | 2 +- .../provider_test.go | 2 +- .../resource_contentful_apikey.go | 2 +- .../resource_contentful_apikey_test.go | 2 +- .../resource_contentful_contenttype.go | 2 +- .../resource_contentful_contenttype_test.go | 2 +- .../resource_contentful_locale.go | 2 +- .../resource_contentful_locale_test.go | 2 +- .../resource_contentful_space.go | 2 +- .../resource_contentful_space_test.go | 2 +- .../resource_contentful_webhook.go | 2 +- .../resource_contentful_webhook_test.go | 2 +- install-dependencies.sh | 7 ---- main.go | 3 +- 19 files changed, 44 insertions(+), 74 deletions(-) delete mode 100644 Dockerfile-test delete mode 100644 circle.yml rename constants.go => contentful/constants.go (96%) rename provider.go => contentful/provider.go (98%) rename provider_test.go => contentful/provider_test.go (98%) rename resource_contentful_apikey.go => contentful/resource_contentful_apikey.go (99%) rename resource_contentful_apikey_test.go => contentful/resource_contentful_apikey_test.go (99%) rename resource_contentful_contenttype.go => contentful/resource_contentful_contenttype.go (99%) rename resource_contentful_contenttype_test.go => contentful/resource_contentful_contenttype_test.go (99%) rename resource_contentful_locale.go => contentful/resource_contentful_locale.go (99%) rename resource_contentful_locale_test.go => contentful/resource_contentful_locale_test.go (99%) rename resource_contentful_space.go => contentful/resource_contentful_space.go (99%) rename resource_contentful_space_test.go => contentful/resource_contentful_space_test.go (98%) rename resource_contentful_webhook.go => contentful/resource_contentful_webhook.go (99%) rename resource_contentful_webhook_test.go => contentful/resource_contentful_webhook_test.go (99%) delete mode 100755 install-dependencies.sh diff --git a/.gitignore b/.gitignore index 62b43e7..3c647cf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,19 @@ terraform-provider-contentful .envrc + +*.backup +/dist/* +coverage.txt + +*.tf +.terraform/ +terraform.* +crash.log + +.vscode +.idea + +/local/* +!/local/*.example + +vendor/ \ No newline at end of file diff --git a/Dockerfile-test b/Dockerfile-test deleted file mode 100644 index 72b719c..0000000 --- a/Dockerfile-test +++ /dev/null @@ -1,11 +0,0 @@ -FROM golang:1.9 - -WORKDIR /go/src/github.com/labd/terraform-contentful - -# http://stackoverflow.com/questions/39278756/cache-go-get-in-docker-build -COPY ./install-dependencies.sh /go/src/github.com/labd/terraform-contentful -RUN ./install-dependencies.sh - -COPY . /go/src/github.com/labd/terraform-contentful - -CMD go test -v diff --git a/Makefile b/Makefile index bce3756..c7af448 100644 --- a/Makefile +++ b/Makefile @@ -1,31 +1,16 @@ -.PHONY: build build: - docker build -t contentful-terraform-test -f Dockerfile-test . + go build -o terraform-provider-contentful -.PHONY: test-unit -test-unit: build - docker run \ - contentful-terraform-test \ - go test -v +format: + go fmt ./... -# Runs an end-to-end integration test using Contentful. -# Requires that the following environment variables are set: -# - CONTENTFUL_MANAGEMENT_TOKEN -# - CONTENTFUL_ORGANIZATION_ID -.PHONY: test-integration -test-integration: build - docker run \ - -e CONTENTFUL_MANAGEMENT_TOKEN \ - -e CONTENTFUL_ORGANIZATION_ID \ - -e "TF_ACC=true" \ - contentful-terraform-test \ - go test -v +test: + TF_ACC=1 go test -v -.PHONY: interactive -interactive: - docker run -it \ - -v $(shell pwd):/go/src/github.com/danihodovic/contentful-terraform \ - -e CONTENTFUL_MANAGEMENT_TOKEN \ - -e CONTENTFUL_ORGANIZATION_ID \ - contentful-terraform-test \ - bash +coverage-html: + go test -race -coverprofile=coverage.txt -covermode=atomic -coverpkg=./... ./... + go tool cover -html=coverage.txt + +coverage: + go test -race -coverprofile=coverage.txt -covermode=atomic -coverpkg=./... ./... + go tool cover -func=coverage.txt diff --git a/circle.yml b/circle.yml deleted file mode 100644 index 1959fde..0000000 --- a/circle.yml +++ /dev/null @@ -1,15 +0,0 @@ -machine: - pre: - # Install docker 1.10.0, can be removed when circle ships it - # https://discuss.circleci.com/t/docker-1-10-0-is-available-beta/2100 - - curl -sSL https://s3.amazonaws.com/circle-downloads/install-circleci-docker.sh | bash -s -- 1.10.0 - services: - - docker - -dependencies: - override: - - make build - -test: - override: - - make test-unit diff --git a/constants.go b/contentful/constants.go similarity index 96% rename from constants.go rename to contentful/constants.go index 5ea01bd..3bff800 100644 --- a/constants.go +++ b/contentful/constants.go @@ -1,4 +1,4 @@ -package main +package contentful import ( "errors" diff --git a/provider.go b/contentful/provider.go similarity index 98% rename from provider.go rename to contentful/provider.go index 945fd71..bc930d0 100644 --- a/provider.go +++ b/contentful/provider.go @@ -1,4 +1,4 @@ -package main +package contentful import ( "os" diff --git a/provider_test.go b/contentful/provider_test.go similarity index 98% rename from provider_test.go rename to contentful/provider_test.go index 8ff6fb1..bec87e8 100644 --- a/provider_test.go +++ b/contentful/provider_test.go @@ -1,4 +1,4 @@ -package main +package contentful import ( "os" diff --git a/resource_contentful_apikey.go b/contentful/resource_contentful_apikey.go similarity index 99% rename from resource_contentful_apikey.go rename to contentful/resource_contentful_apikey.go index 2de94d7..1e9dffa 100644 --- a/resource_contentful_apikey.go +++ b/contentful/resource_contentful_apikey.go @@ -1,4 +1,4 @@ -package main +package contentful import ( "github.com/hashicorp/terraform/helper/schema" diff --git a/resource_contentful_apikey_test.go b/contentful/resource_contentful_apikey_test.go similarity index 99% rename from resource_contentful_apikey_test.go rename to contentful/resource_contentful_apikey_test.go index 2b76185..0639b09 100644 --- a/resource_contentful_apikey_test.go +++ b/contentful/resource_contentful_apikey_test.go @@ -1,4 +1,4 @@ -package main +package contentful import ( "fmt" diff --git a/resource_contentful_contenttype.go b/contentful/resource_contentful_contenttype.go similarity index 99% rename from resource_contentful_contenttype.go rename to contentful/resource_contentful_contenttype.go index 116932e..8b90c63 100644 --- a/resource_contentful_contenttype.go +++ b/contentful/resource_contentful_contenttype.go @@ -1,4 +1,4 @@ -package main +package contentful import ( "github.com/hashicorp/terraform/helper/schema" diff --git a/resource_contentful_contenttype_test.go b/contentful/resource_contentful_contenttype_test.go similarity index 99% rename from resource_contentful_contenttype_test.go rename to contentful/resource_contentful_contenttype_test.go index fa1afdb..823d28b 100644 --- a/resource_contentful_contenttype_test.go +++ b/contentful/resource_contentful_contenttype_test.go @@ -1,4 +1,4 @@ -package main +package contentful import ( "fmt" diff --git a/resource_contentful_locale.go b/contentful/resource_contentful_locale.go similarity index 99% rename from resource_contentful_locale.go rename to contentful/resource_contentful_locale.go index 1c51b50..366f17f 100644 --- a/resource_contentful_locale.go +++ b/contentful/resource_contentful_locale.go @@ -1,4 +1,4 @@ -package main +package contentful import ( "github.com/hashicorp/terraform/helper/schema" diff --git a/resource_contentful_locale_test.go b/contentful/resource_contentful_locale_test.go similarity index 99% rename from resource_contentful_locale_test.go rename to contentful/resource_contentful_locale_test.go index b4ba1b6..c6241e6 100644 --- a/resource_contentful_locale_test.go +++ b/contentful/resource_contentful_locale_test.go @@ -1,4 +1,4 @@ -package main +package contentful import ( "fmt" diff --git a/resource_contentful_space.go b/contentful/resource_contentful_space.go similarity index 99% rename from resource_contentful_space.go rename to contentful/resource_contentful_space.go index 0f7288c..eb77101 100644 --- a/resource_contentful_space.go +++ b/contentful/resource_contentful_space.go @@ -1,4 +1,4 @@ -package main +package contentful import ( "github.com/hashicorp/terraform/helper/schema" diff --git a/resource_contentful_space_test.go b/contentful/resource_contentful_space_test.go similarity index 98% rename from resource_contentful_space_test.go rename to contentful/resource_contentful_space_test.go index f52b856..56341b1 100644 --- a/resource_contentful_space_test.go +++ b/contentful/resource_contentful_space_test.go @@ -1,4 +1,4 @@ -package main +package contentful import ( "fmt" diff --git a/resource_contentful_webhook.go b/contentful/resource_contentful_webhook.go similarity index 99% rename from resource_contentful_webhook.go rename to contentful/resource_contentful_webhook.go index 60f338a..fbb2351 100644 --- a/resource_contentful_webhook.go +++ b/contentful/resource_contentful_webhook.go @@ -1,4 +1,4 @@ -package main +package contentful import ( "github.com/hashicorp/terraform/helper/schema" diff --git a/resource_contentful_webhook_test.go b/contentful/resource_contentful_webhook_test.go similarity index 99% rename from resource_contentful_webhook_test.go rename to contentful/resource_contentful_webhook_test.go index a4a6bb3..005ebf2 100644 --- a/resource_contentful_webhook_test.go +++ b/contentful/resource_contentful_webhook_test.go @@ -1,4 +1,4 @@ -package main +package contentful import ( "fmt" diff --git a/install-dependencies.sh b/install-dependencies.sh deleted file mode 100755 index 64a0a61..0000000 --- a/install-dependencies.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env bash -# Let's avoid rebuilding the dependencies each time a source file changes. -# See: http://stackoverflow.com/questions/39278756/cache-go-get-in-docker-build -go get github.com/hashicorp/terraform/terraform -go get github.com/hashicorp/terraform/helper/resource -go get github.com/hashicorp/terraform/helper/schema -go get github.com/labd/contentful-go diff --git a/main.go b/main.go index 5ecf31e..ff4faff 100644 --- a/main.go +++ b/main.go @@ -3,12 +3,13 @@ package main import ( "github.com/hashicorp/terraform/plugin" "github.com/hashicorp/terraform/terraform" + "github.com/labd/terraform-contentful/contentful" ) func main() { plugin.Serve(&plugin.ServeOpts{ ProviderFunc: func() terraform.ResourceProvider { - return Provider() + return contentful.Provider() }, }) } From 2f42852d0f0454e283a1b9dcb2f0a15c474c5660 Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Thu, 16 Apr 2020 14:31:17 +0200 Subject: [PATCH 043/192] Minor changes The space resource is now skipped while testing. This is because I, along with many other Contentful users do not have permissions to change, create or delete spaces within an organization. The Space resource test will fail in this case, so for now it is skipped. --- Makefile | 29 +++++++++++-------- contentful/resource_contentful_space_test.go | 3 +- .../resource_contentful_webhook_test.go | 16 ++-------- tools/install-dependencies.sh | 6 ++++ tools/test.sh | 20 +++++++++++++ 5 files changed, 48 insertions(+), 26 deletions(-) create mode 100755 tools/install-dependencies.sh create mode 100755 tools/test.sh diff --git a/Makefile b/Makefile index c7af448..3b8d599 100644 --- a/Makefile +++ b/Makefile @@ -1,16 +1,21 @@ -build: - go build -o terraform-provider-contentful +GO_CMD=go +GO_BUILD=$(GO_CMD) build +GO_BUILD_RACE=$(GO_CMD) build -race +GO_TEST=$(GO_CMD) test +GO_TEST_VERBOSE=$(GO_CMD) test -v +GO_INSTALL=$(GO_CMD) install -v +GO_CLEAN=$(GO_CMD) clean +GO_DEPS=$(GO_CMD) get -d -v +GO_DEPS_UPDATE=$(GO_CMD) get -d -v -u +GO_VET=$(GO_CMD) vet +GO_FMT=$(GO_CMD) fmt -format: - go fmt ./... +.PHONY: all test format dep -test: - TF_ACC=1 go test -v +all: dep test format -coverage-html: - go test -race -coverprofile=coverage.txt -covermode=atomic -coverpkg=./... ./... - go tool cover -html=coverage.txt +test: + ./tools/test.sh -coverage: - go test -race -coverprofile=coverage.txt -covermode=atomic -coverpkg=./... ./... - go tool cover -func=coverage.txt +format: + go fmt diff --git a/contentful/resource_contentful_space_test.go b/contentful/resource_contentful_space_test.go index 56341b1..b82cdf8 100644 --- a/contentful/resource_contentful_space_test.go +++ b/contentful/resource_contentful_space_test.go @@ -10,6 +10,7 @@ import ( ) func TestAccContentfulSpace_Basic(t *testing.T) { + t.Skip() // Space resource can only be tested when user has the rights to do so, if not, skip this test! resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, @@ -48,7 +49,7 @@ func testAccCheckContentfulSpaceDestroy(s *terraform.State) error { var testAccContentfulSpaceConfig = ` resource "contentful_space" "myspace" { - name = "TF Acc Test Space" + name = "Playground" } ` diff --git a/contentful/resource_contentful_webhook_test.go b/contentful/resource_contentful_webhook_test.go index 005ebf2..32d3195 100644 --- a/contentful/resource_contentful_webhook_test.go +++ b/contentful/resource_contentful_webhook_test.go @@ -131,13 +131,8 @@ func testAccContentfulWebhookDestroy(s *terraform.State) error { } var testAccContentfulWebhookConfig = ` -resource "contentful_space" "myspace" { - name = "space-name" -} - resource "contentful_webhook" "mywebhook" { - space_id = "${contentful_space.myspace.id}" - depends_on = ["contentful_space.myspace"] + space_id = "uhwvl4veejyj" name = "webhook-name" url= "https://www.example.com/test" @@ -145,7 +140,7 @@ resource "contentful_webhook" "mywebhook" { "Entry.create", "ContentType.create", ] - headers { + headers = { header1 = "header1-value" header2 = "header2-value" } @@ -155,13 +150,8 @@ resource "contentful_webhook" "mywebhook" { ` var testAccContentfulWebhookUpdateConfig = ` -resource "contentful_space" "myspace" { - name = "space-name" -} - resource "contentful_webhook" "mywebhook" { - depends_on = ["contentful_space.myspace"] - space_id = "${contentful_space.myspace.id}" + space_id = "uhwvl4veejyj" name = "webhook-name-updated" url= "https://www.example.com/test-updated" diff --git a/tools/install-dependencies.sh b/tools/install-dependencies.sh new file mode 100755 index 0000000..e2c4911 --- /dev/null +++ b/tools/install-dependencies.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +go get github.com/hashicorp/terraform/terraform +go get github.com/hashicorp/terraform/helper/resource +go get github.com/hashicorp/terraform/helper/schema +go get github.com/labd/contentful-go diff --git a/tools/test.sh b/tools/test.sh new file mode 100755 index 0000000..f2234f1 --- /dev/null +++ b/tools/test.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash +set -e + +rm coverage.txt || true +touch coverage.txt + +for d in $(go list ./... | grep -v /vendor/); do + TF_ACC=1 go test -v -coverprofile=profile.out -covermode=count "$d" + + if [ -f profile.out ]; then + cat profile.out >> coverage.txt + rm profile.out + fi +done + +# to make `go tool cover -html=coverage.txt` happy +# remove the lines starting with mode +# remove the empty lines +sed -i'' -e '/^\s*$/d' coverage.txt +echo "$(awk '!/^mode:/ || !f++' coverage.txt)" > coverage.txt From b39551db681b00915273b6c554e642ec3c370f3d Mon Sep 17 00:00:00 2001 From: Jasper Berghoef Date: Thu, 16 Apr 2020 16:02:15 +0200 Subject: [PATCH 044/192] Rename circle.yml to .circleci/config.yml --- circle.yml => .circleci/config.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename circle.yml => .circleci/config.yml (100%) diff --git a/circle.yml b/.circleci/config.yml similarity index 100% rename from circle.yml rename to .circleci/config.yml From f8cccabe76660ccec2de36693cda95b6ff970266 Mon Sep 17 00:00:00 2001 From: Jasper Berghoef Date: Thu, 16 Apr 2020 16:11:02 +0200 Subject: [PATCH 045/192] Create go.yml --- .github/workflows/go.yml | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 .github/workflows/go.yml diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml new file mode 100644 index 0000000..717a57b --- /dev/null +++ b/.github/workflows/go.yml @@ -0,0 +1,40 @@ +name: Go + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + + build: + name: Build + runs-on: ubuntu-latest + steps: + + - name: Set up Go 1.13 + uses: actions/setup-go@v1 + with: + go-version: 1.13 + id: go + + - name: Check out code into the Go module directory + uses: actions/checkout@v2 + + - name: Get dependencies + run: | + go get -v -t -d ./... + if [ -f Gopkg.toml ]; then + curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh + dep ensure + fi + + - name: Build + run: go build -v . + test: + name: Test + runs-on: ubuntu-latest + steps: + - name: Test + run: go test -v . From f794e2bad731b3c6973f746441cf3d386f0527cd Mon Sep 17 00:00:00 2001 From: Jasper Berghoef Date: Thu, 16 Apr 2020 16:13:40 +0200 Subject: [PATCH 046/192] Update go.yml --- .github/workflows/go.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 717a57b..b8a214f 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -13,10 +13,10 @@ jobs: runs-on: ubuntu-latest steps: - - name: Set up Go 1.13 + - name: Set up Go 1.9 uses: actions/setup-go@v1 with: - go-version: 1.13 + go-version: 1.9 id: go - name: Check out code into the Go module directory @@ -35,6 +35,7 @@ jobs: test: name: Test runs-on: ubuntu-latest + needs: [build] steps: - name: Test run: go test -v . From 2369c74c12407d63a496d64c51eb22becef5ff7f Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Thu, 16 Apr 2020 16:15:49 +0200 Subject: [PATCH 047/192] Space id to environment variable Changed space id into an environment variable. --- contentful/constants.go | 2 ++ contentful/resource_contentful_apikey_test.go | 10 ++++++---- contentful/resource_contentful_contenttype_test.go | 8 ++++---- contentful/resource_contentful_locale_test.go | 6 ++++-- contentful/resource_contentful_webhook_test.go | 7 +++++-- 5 files changed, 21 insertions(+), 12 deletions(-) diff --git a/contentful/constants.go b/contentful/constants.go index 3bff800..3beaa75 100644 --- a/contentful/constants.go +++ b/contentful/constants.go @@ -2,12 +2,14 @@ package contentful import ( "errors" + "os" ) // noinspection GoUnusedGlobalVariable var ( baseURL = "https://api.contentful.com" contentfulContentType = "application/vnd.contentful.management.v1+json" + spaceID = os.Getenv("SPACE_ID") // User friendly errors we return errorUnauthorized = errors.New("401 Unauthorized. Is the CMA token valid") errorSpaceNotFound = errors.New("space not found") diff --git a/contentful/resource_contentful_apikey_test.go b/contentful/resource_contentful_apikey_test.go index 0639b09..b8a3160 100644 --- a/contentful/resource_contentful_apikey_test.go +++ b/contentful/resource_contentful_apikey_test.go @@ -26,6 +26,7 @@ func TestAccContentfulAPIKey_Basic(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckContentfulAPIKeyExists("contentful_apikey.myapikey", &apiKey), testAccCheckContentfulAPIKeyAttributes(&apiKey, map[string]interface{}{ + "space_id": spaceID, "name": name, "description": description, }), @@ -36,6 +37,7 @@ func TestAccContentfulAPIKey_Basic(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckContentfulAPIKeyExists("contentful_apikey.myapikey", &apiKey), testAccCheckContentfulAPIKeyAttributes(&apiKey, map[string]interface{}{ + "space_id": spaceID, "name": fmt.Sprintf("%s-updated", name), "description": fmt.Sprintf("%s-updated", description), }), @@ -124,21 +126,21 @@ func testAccContentfulAPIKeyDestroy(s *terraform.State) error { func testAccContentfulAPIKeyConfig(name, description string) string { return fmt.Sprintf(` resource "contentful_apikey" "myapikey" { - space_id = "uhwvl4veejyj" + space_id = "%s" name = "%s" description = "%s" } -`, name, description) +`, spaceID, name, description) } func testAccContentfulAPIKeyUpdateConfig(name, description string) string { return fmt.Sprintf(` resource "contentful_apikey" "myapikey" { - space_id = "uhwvl4veejyj" + space_id = "%s" name = "%s-updated" description = "%s-updated" } -`, name, description) +`, spaceID, name, description) } diff --git a/contentful/resource_contentful_contenttype_test.go b/contentful/resource_contentful_contenttype_test.go index 823d28b..298624a 100644 --- a/contentful/resource_contentful_contenttype_test.go +++ b/contentful/resource_contentful_contenttype_test.go @@ -90,7 +90,7 @@ func testAccCheckContentfulContentTypeDestroy(s *terraform.State) (err error) { var testAccContentfulContentTypeConfig = ` resource "contentful_contenttype" "mycontenttype" { - space_id = "uhwvl4veejyj" + space_id = "` + spaceID + `" name = "TF Acc Test CT 1" description = "Terraform Acc Test Content Type" display_field = "field1" @@ -117,7 +117,7 @@ resource "contentful_contenttype" "mycontenttype" { var testAccContentfulContentTypeUpdateConfig = ` resource "contentful_contenttype" "mycontenttype" { - space_id = "uhwvl4veejyj" + space_id = "` + spaceID + `" name = "TF Acc Test CT name change" description = "Terraform Acc Test Content Type description change" display_field = "field1" @@ -144,7 +144,7 @@ resource "contentful_contenttype" "mycontenttype" { var testAccContentfulContentTypeLinkConfig = ` resource "contentful_contenttype" "mycontenttype" { - space_id = "uhwvl4veejyj" + space_id = "` + spaceID + `" name = "TF Acc Test CT name change" description = "Terraform Acc Test Content Type description change" display_field = "field1" @@ -169,7 +169,7 @@ resource "contentful_contenttype" "mycontenttype" { } resource "contentful_contenttype" "mylinked_contenttype" { - space_id = "uhwvl4veejyj" + space_id = "` + spaceID + `" name = "TF Acc Test Linked CT" description = "Terraform Acc Test Content Type with links" display_field = "asset_field" diff --git a/contentful/resource_contentful_locale_test.go b/contentful/resource_contentful_locale_test.go index c6241e6..8afe7f3 100644 --- a/contentful/resource_contentful_locale_test.go +++ b/contentful/resource_contentful_locale_test.go @@ -22,6 +22,7 @@ func TestAccContentfulLocales_Basic(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckContentfulLocaleExists("contentful_locale.mylocale", &locale), testAccCheckContentfulLocaleAttributes(&locale, map[string]interface{}{ + "space_id": spaceID, "name": "locale-name", "code": "de", "fallback_code": "en-US", @@ -36,6 +37,7 @@ func TestAccContentfulLocales_Basic(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckContentfulLocaleExists("contentful_locale.mylocale", &locale), testAccCheckContentfulLocaleAttributes(&locale, map[string]interface{}{ + "space_id": spaceID, "name": "locale-name-updated", "code": "es", "fallback_code": "en-US", @@ -146,7 +148,7 @@ func testAccContentfulLocaleDestroy(s *terraform.State) error { var testAccContentfulLocaleConfig = ` resource "contentful_locale" "mylocale" { - space_id = "uhwvl4veejyj" + space_id = "` + spaceID + `" name = "locale-name" code = "de" @@ -159,7 +161,7 @@ resource "contentful_locale" "mylocale" { var testAccContentfulLocaleUpdateConfig = ` resource "contentful_locale" "mylocale" { - space_id = "uhwvl4veejyj" + space_id = "` + spaceID + `" name = "locale-name-updated" code = "es" diff --git a/contentful/resource_contentful_webhook_test.go b/contentful/resource_contentful_webhook_test.go index 32d3195..16a39eb 100644 --- a/contentful/resource_contentful_webhook_test.go +++ b/contentful/resource_contentful_webhook_test.go @@ -22,6 +22,7 @@ func TestAccContentfulWebhook_Basic(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckContentfulWebhookExists("contentful_webhook.mywebhook", &webhook), testAccCheckContentfulWebhookAttributes(&webhook, map[string]interface{}{ + "space_id": spaceID, "name": "webhook-name", "url": "https://www.example.com/test", "http_basic_auth_username": "username", @@ -33,6 +34,7 @@ func TestAccContentfulWebhook_Basic(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckContentfulWebhookExists("contentful_webhook.mywebhook", &webhook), testAccCheckContentfulWebhookAttributes(&webhook, map[string]interface{}{ + "space_id": spaceID, "name": "webhook-name-updated", "url": "https://www.example.com/test-updated", "http_basic_auth_username": "username-updated", @@ -132,7 +134,7 @@ func testAccContentfulWebhookDestroy(s *terraform.State) error { var testAccContentfulWebhookConfig = ` resource "contentful_webhook" "mywebhook" { - space_id = "uhwvl4veejyj" + space_id = "` + spaceID + `" name = "webhook-name" url= "https://www.example.com/test" @@ -151,7 +153,8 @@ resource "contentful_webhook" "mywebhook" { var testAccContentfulWebhookUpdateConfig = ` resource "contentful_webhook" "mywebhook" { - space_id = "uhwvl4veejyj" + space_id = "` + spaceID + `" + name = "webhook-name-updated" url= "https://www.example.com/test-updated" From 39d7b1095377fe42e4b7fe1d39f29c67b6cd3134 Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Fri, 17 Apr 2020 11:21:29 +0200 Subject: [PATCH 048/192] Docker working Updated the config and makefile to work with the newest versions of Docker and GO --- .circleci/config.yml | 15 +++++++ .github/workflows/go.yml | 40 +++++++++++++++++++ .gitignore | 2 +- Dockerfile-test | 11 +++++ Makefile | 40 +++++++++++-------- ...dependencies.sh => install-dependencies.sh | 0 6 files changed, 90 insertions(+), 18 deletions(-) create mode 100644 .circleci/config.yml create mode 100644 .github/workflows/go.yml create mode 100644 Dockerfile-test rename tools/install-dependencies.sh => install-dependencies.sh (100%) diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000..05e4088 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,15 @@ +machine: + pre: + # Install docker 1.10.0, can be removed when circle ships it + # https://discuss.circleci.com/t/docker-1-10-0-is-available-beta/2100 + - curl -sSL https://s3.amazonaws.com/circle-downloads/install-circleci-docker.sh | bash -s -- 1.10.0 + services: + - docker + +dependencies: + override: + - make build + +test: + override: + - make test-unit \ No newline at end of file diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml new file mode 100644 index 0000000..47e1a3d --- /dev/null +++ b/.github/workflows/go.yml @@ -0,0 +1,40 @@ +name: Go + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + + build: + name: Build + runs-on: ubuntu-latest + steps: + + - name: Set up Go 1.9 + uses: actions/setup-go@v1 + with: + go-version: 1.9 + id: go + + - name: Check out code into the Go module directory + uses: actions/checkout@v2 + + - name: Get dependencies + run: | + go get -v -t -d ./... + if [ -f Gopkg.toml ]; then + curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh + dep ensure + fi + - name: Build + run: go build -v . + test: + name: Test + runs-on: ubuntu-latest + needs: [build] + steps: + - name: Test + run: go test -v . \ No newline at end of file diff --git a/.gitignore b/.gitignore index 3c647cf..15dc197 100644 --- a/.gitignore +++ b/.gitignore @@ -13,7 +13,7 @@ crash.log .vscode .idea -/local/* +local/ !/local/*.example vendor/ \ No newline at end of file diff --git a/Dockerfile-test b/Dockerfile-test new file mode 100644 index 0000000..c03abc1 --- /dev/null +++ b/Dockerfile-test @@ -0,0 +1,11 @@ +FROM golang:1.14.2 + +WORKDIR /go/src/github.com/labd/terraform-contentful + +# http://stackoverflow.com/questions/39278756/cache-go-get-in-docker-build +COPY ./install-dependencies.sh /go/src/github.com/labd/terraform-contentful +RUN ./install-dependencies.sh + +COPY . /go/src/github.com/labd/terraform-contentful + +CMD go test -v \ No newline at end of file diff --git a/Makefile b/Makefile index 3b8d599..bfaf9e0 100644 --- a/Makefile +++ b/Makefile @@ -1,21 +1,27 @@ -GO_CMD=go -GO_BUILD=$(GO_CMD) build -GO_BUILD_RACE=$(GO_CMD) build -race -GO_TEST=$(GO_CMD) test -GO_TEST_VERBOSE=$(GO_CMD) test -v -GO_INSTALL=$(GO_CMD) install -v -GO_CLEAN=$(GO_CMD) clean -GO_DEPS=$(GO_CMD) get -d -v -GO_DEPS_UPDATE=$(GO_CMD) get -d -v -u -GO_VET=$(GO_CMD) vet -GO_FMT=$(GO_CMD) fmt +GOCMD=go +CMT=$(GOCMD) os.Getenv("CONTENTFUL_MANAGEMENT_TOKEN") -.PHONY: all test format dep -all: dep test format +.PHONY: build +build: + sudo -S docker build -t terraform-provider-contentful -f Dockerfile-test . -test: - ./tools/test.sh +.PHONY: test-unit +test-unit: build + sudo docker run \ + -e CONTENTFUL_MANAGEMENT_TOKEN=${CONTENTFUL_MANAGEMENT_TOKEN} \ + -e CONTENTFUL_ORGANIZATION_ID=${CONTENTFUL_ORGANIZATION_ID} \ + -e SPACE_ID=${SPACE_ID} \ + -e "TF_ACC=true" \ + terraform-provider-contentful \ + go test ./... -v -format: - go fmt +.PHONY: interactive +interactive: + sudo -S docker run -it \ + -v $(shell pwd):/go/src/github.com/labd/terraform-contentful \ + -e CONTENTFUL_MANAGEMENT_TOKEN=${CONTENTFUL_MANAGEMENT_TOKEN} \ + -e CONTENTFUL_ORGANIZATION_ID=${CONTENTFUL_ORGANIZATION_ID} \ + -e SPACE_ID=${SPACE_ID} \ + terraform-provider-contentful \ + bash diff --git a/tools/install-dependencies.sh b/install-dependencies.sh similarity index 100% rename from tools/install-dependencies.sh rename to install-dependencies.sh From efbd7b2e7e5dcc62e6d43759a3d65fe8e3c0056c Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Fri, 17 Apr 2020 11:22:33 +0200 Subject: [PATCH 049/192] removed some redundant code --- Makefile | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Makefile b/Makefile index bfaf9e0..3b44a7a 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,3 @@ -GOCMD=go -CMT=$(GOCMD) os.Getenv("CONTENTFUL_MANAGEMENT_TOKEN") - - .PHONY: build build: sudo -S docker build -t terraform-provider-contentful -f Dockerfile-test . From e07dfc3838d80a2c20c9ccd1f06f14a887e4e035 Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Mon, 20 Apr 2020 11:29:45 +0200 Subject: [PATCH 050/192] go mod versioning fix --- go.mod | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 go.mod diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..f56f7b6 --- /dev/null +++ b/go.mod @@ -0,0 +1,8 @@ +module github.com/labd/terraform-contentful + +go 1.14 + +require ( + github.com/hashicorp/terraform v0.12.24 + github.com/labd/contentful-go v0.4.1-0.20200420081834-f20ec0d2853f +) From 28f0dcdc214ce61b7ed70a46d642048e3c0a31c1 Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Mon, 20 Apr 2020 11:47:33 +0200 Subject: [PATCH 051/192] go test wildcard fix --- .github/workflows/go.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 4970469..3b8a35e 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -37,4 +37,4 @@ jobs: needs: [build] steps: - name: Test - run: go test -v . \ No newline at end of file + run: go test ./... -v \ No newline at end of file From 47900093e6ddd0b966d50382204f7973dc1e23d1 Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Mon, 20 Apr 2020 11:54:41 +0200 Subject: [PATCH 052/192] go test wildcard? --- .github/workflows/go.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 3b8a35e..f46c267 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -37,4 +37,4 @@ jobs: needs: [build] steps: - name: Test - run: go test ./... -v \ No newline at end of file + run: go test ./contentful -v \ No newline at end of file From 914fb72a6de44bddd794c9f4106e079d96ad5c7b Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Mon, 20 Apr 2020 12:08:04 +0200 Subject: [PATCH 053/192] Hoping this works... --- .github/workflows/go.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index f46c267..4008914 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -37,4 +37,4 @@ jobs: needs: [build] steps: - name: Test - run: go test ./contentful -v \ No newline at end of file + run: go test -v ../../... \ No newline at end of file From 62088e020e1568028010ff3913eafd46a77db112 Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Mon, 20 Apr 2020 12:17:06 +0200 Subject: [PATCH 054/192] Maybe this? --- .github/workflows/go.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 4008914..447abad 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -37,4 +37,4 @@ jobs: needs: [build] steps: - name: Test - run: go test -v ../../... \ No newline at end of file + run: go test -v . ./contentful \ No newline at end of file From 6bd6f78cc00e0933e8d84db42e4c40dae370d64f Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Mon, 20 Apr 2020 12:20:21 +0200 Subject: [PATCH 055/192] test config change --- .github/workflows/go.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 447abad..4ae6da3 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -37,4 +37,4 @@ jobs: needs: [build] steps: - name: Test - run: go test -v . ./contentful \ No newline at end of file + run: go test -v ../contentful \ No newline at end of file From ec1582beb6312b1f90fcddf078e1dca0e4837007 Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Mon, 20 Apr 2020 12:22:54 +0200 Subject: [PATCH 056/192] test config change --- .github/workflows/go.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 4ae6da3..7ffd0a9 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -37,4 +37,4 @@ jobs: needs: [build] steps: - name: Test - run: go test -v ../contentful \ No newline at end of file + run: go test -v ./contentful \ No newline at end of file From eee4c7b1bffb5f5a1eebf11ade2d9429abe4f41a Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Mon, 20 Apr 2020 12:26:36 +0200 Subject: [PATCH 057/192] test config change --- .github/workflows/go.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 7ffd0a9..02dd19a 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -37,4 +37,4 @@ jobs: needs: [build] steps: - name: Test - run: go test -v ./contentful \ No newline at end of file + run: go test -v ./... \ No newline at end of file From a257694f199804ddc44ed1fafe5d6396ed5cc975 Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Mon, 20 Apr 2020 13:59:10 +0200 Subject: [PATCH 058/192] test config change --- .github/workflows/go.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 02dd19a..fc606c7 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -36,5 +36,9 @@ jobs: runs-on: ubuntu-latest needs: [build] steps: - - name: Test - run: go test -v ./... \ No newline at end of file + - name: Install dependencies + run: go get ./contentful + - name: Run tests + run: go test -race -coverprofile=coverage.txt -covermode=atomic -coverpkg=./contentful -v ./contentful + - name: Upload to codecov + uses: codecov/codecov-action@v1.0.6 \ No newline at end of file From 90f9df8f890b03816ea0b1470326e7b97fbeb948 Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Mon, 20 Apr 2020 14:17:06 +0200 Subject: [PATCH 059/192] test config change --- .github/workflows/go.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index fc606c7..c2f031b 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -36,9 +36,21 @@ jobs: runs-on: ubuntu-latest needs: [build] steps: + + - name: Set up Go 1.14.2 + uses: actions/setup-go@v1 + with: + go-version: 1.14.2 + id: go + + - name: Check out code into the Go module directory + uses: actions/checkout@v2 + - name: Install dependencies run: go get ./contentful + - name: Run tests run: go test -race -coverprofile=coverage.txt -covermode=atomic -coverpkg=./contentful -v ./contentful + - name: Upload to codecov uses: codecov/codecov-action@v1.0.6 \ No newline at end of file From 31876709345d6281d205aa05d148fea84684d40b Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Mon, 20 Apr 2020 14:19:24 +0200 Subject: [PATCH 060/192] test config change --- .github/workflows/go.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index c2f031b..0d2c851 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -38,19 +38,19 @@ jobs: steps: - name: Set up Go 1.14.2 - uses: actions/setup-go@v1 - with: - go-version: 1.14.2 - id: go + uses: actions/setup-go@v1 + with: + go-version: 1.14.2 + id: go - name: Check out code into the Go module directory uses: actions/checkout@v2 - name: Install dependencies - run: go get ./contentful + run: go get ./contentful - name: Run tests - run: go test -race -coverprofile=coverage.txt -covermode=atomic -coverpkg=./contentful -v ./contentful + run: go test -race -coverprofile=coverage.txt -covermode=atomic -coverpkg=./contentful -v ./contentful - name: Upload to codecov uses: codecov/codecov-action@v1.0.6 \ No newline at end of file From 950bec507fdbb2f279b0ce7f80d3ec94e70bd45e Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Mon, 20 Apr 2020 14:37:48 +0200 Subject: [PATCH 061/192] test config change --- .github/workflows/go.yml | 66 ++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 37 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 0d2c851..cc4be5f 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -12,45 +12,37 @@ jobs: name: Build runs-on: ubuntu-latest steps: - - - name: Set up Go 1.14.2 - uses: actions/setup-go@v1 - with: - go-version: 1.14.2 - id: go - - - name: Check out code into the Go module directory - uses: actions/checkout@v2 - - - name: Get dependencies - run: | - go get -v -t -d ./... - if [ -f Gopkg.toml ]; then - curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh - dep ensure - fi - - name: Build - run: go build -v . + - name: Set up Go 1.14.2 + uses: actions/setup-go@v1 + with: + go-version: 1.14.2 + id: go + - name: Check out code into the Go module directory + uses: actions/checkout@v2 + - name: Get dependencies + run: | + go get -v -t -d ./... + if [ -f Gopkg.toml ]; then + curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh + dep ensure + fi + - name: Build + run: go build -v . test: name: Test runs-on: ubuntu-latest needs: [build] steps: - - - name: Set up Go 1.14.2 - uses: actions/setup-go@v1 - with: - go-version: 1.14.2 - id: go - - - name: Check out code into the Go module directory - uses: actions/checkout@v2 - - - name: Install dependencies - run: go get ./contentful - - - name: Run tests - run: go test -race -coverprofile=coverage.txt -covermode=atomic -coverpkg=./contentful -v ./contentful - - - name: Upload to codecov - uses: codecov/codecov-action@v1.0.6 \ No newline at end of file + - name: Set up Go 1.14.2 + uses: actions/setup-go@v1 + with: + go-version: 1.14.2 + id: go + - name: Check out code into the Go module directory + uses: actions/checkout@v2 + - name: Install dependencies + run: go get ./contentful + - name: Run tests + run: go test -race -coverprofile=coverage.txt -covermode=atomic -coverpkg=./contentful -v ./contentful + - name: Upload to codecov + uses: codecov/codecov-action@v1.0.6 \ No newline at end of file From dc16e9bffb32837b70ff62035efb8f1f7023c7fe Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Mon, 20 Apr 2020 16:14:25 +0200 Subject: [PATCH 062/192] test config now using secrets as environment variables for tests. --- .github/workflows/go.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index cc4be5f..f465df4 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -44,5 +44,9 @@ jobs: run: go get ./contentful - name: Run tests run: go test -race -coverprofile=coverage.txt -covermode=atomic -coverpkg=./contentful -v ./contentful + env: + CONTENTFUL_ORGANIZATION_ID: ${{ secrets.CONTENTFUL_ORGANIZATION_ID }} + CONTENTFUL_MANAGEMENT_TOKEN: ${{ secrets.CONTENTFUL_MANAGEMENT_TOKEN }} + SPACE_ID: ${{ secrets.SPACE_ID }} - name: Upload to codecov uses: codecov/codecov-action@v1.0.6 \ No newline at end of file From 854c02acae1c5d839b0cdfaf6db6955b7465e24d Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Mon, 20 Apr 2020 16:19:42 +0200 Subject: [PATCH 063/192] Terraform account boolean now set to True/1 --- .github/workflows/go.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index f465df4..5b709ae 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -45,6 +45,7 @@ jobs: - name: Run tests run: go test -race -coverprofile=coverage.txt -covermode=atomic -coverpkg=./contentful -v ./contentful env: + TF_ACC: 1 CONTENTFUL_ORGANIZATION_ID: ${{ secrets.CONTENTFUL_ORGANIZATION_ID }} CONTENTFUL_MANAGEMENT_TOKEN: ${{ secrets.CONTENTFUL_MANAGEMENT_TOKEN }} SPACE_ID: ${{ secrets.SPACE_ID }} From 2cdda343469fb7bdfbc07f594cee5b5933f03bd2 Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Mon, 20 Apr 2020 16:44:49 +0200 Subject: [PATCH 064/192] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4ddae03..d797c8c 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -[![Build Status](https://img.shields.io/circleci/project/github/contentful-labs/terraform-contentful.svg?branch=master)](https://circleci.com/gh/contentful-labs/terraform-contentful) -[![license](https://img.shields.io/github/license/contentful-labs/terraform-contentful.svg)](https://github.com/contentful-labs/terraform-contentful/blob/master/LICENSE) +[![Build Status](https://img.shields.io/circleci/project/github/labd/terraform-contentful.svg?branch=master)](https://circleci.com/gh/labd/terraform-contentful) +[![license](https://img.shields.io/github/license/contentful-labs/terraform-contentful.svg)](https://github.com/labd/terraform-contentful/blob/master/LICENSE) Terraform Provider for [Contentful's](https://www.contentful.com) Content Management API From c256d5fe504d47b889a7815909350424ac4aaed9 Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Mon, 20 Apr 2020 16:57:12 +0200 Subject: [PATCH 065/192] Updated ReadMe to display correct project data. --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d797c8c..084df05 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ -[![Build Status](https://img.shields.io/circleci/project/github/labd/terraform-contentful.svg?branch=master)](https://circleci.com/gh/labd/terraform-contentful) +![Go](https://github.com/labd/terraform-contentful/workflows/Go/badge.svg?branch=master) +[![codecov](https://codecov.io/gh/labd/terraform-contentful/branch/master/graph/badge.svg)](https://codecov.io/gh/labd/terraform-contentful) [![license](https://img.shields.io/github/license/contentful-labs/terraform-contentful.svg)](https://github.com/labd/terraform-contentful/blob/master/LICENSE) Terraform Provider for [Contentful's](https://www.contentful.com) Content Management API From aae92e7942c3ff47375367e7b64d71753f46c0fd Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Thu, 23 Apr 2020 12:22:35 +0200 Subject: [PATCH 066/192] Added Environments as resources for the provider. The provider is now able to create, read, update and delete the environments inside Contentful. --- .circleci/config.yml | 15 --- LICENSE | 2 +- README.md | 29 ++-- contentful/constants.go | 18 +-- contentful/provider.go | 8 +- contentful/provider_test.go | 5 +- contentful/resource_contentful_contenttype.go | 2 +- contentful/resource_contentful_environment.go | 120 +++++++++++++++++ .../resource_contentful_environment_test.go | 125 ++++++++++++++++++ go.mod | 2 +- tools/test.sh | 20 --- 11 files changed, 282 insertions(+), 64 deletions(-) delete mode 100644 .circleci/config.yml create mode 100644 contentful/resource_contentful_environment.go create mode 100644 contentful/resource_contentful_environment_test.go delete mode 100755 tools/test.sh diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index 1959fde..0000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,15 +0,0 @@ -machine: - pre: - # Install docker 1.10.0, can be removed when circle ships it - # https://discuss.circleci.com/t/docker-1-10-0-is-available-beta/2100 - - curl -sSL https://s3.amazonaws.com/circle-downloads/install-circleci-docker.sh | bash -s -- 1.10.0 - services: - - docker - -dependencies: - override: - - make build - -test: - override: - - make test-unit diff --git a/LICENSE b/LICENSE index d8b47e8..38e31bc 100644 --- a/LICENSE +++ b/LICENSE @@ -14,7 +14,7 @@ copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE diff --git a/README.md b/README.md index 084df05..89d9180 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,11 @@ ![Go](https://github.com/labd/terraform-contentful/workflows/Go/badge.svg?branch=master) [![codecov](https://codecov.io/gh/labd/terraform-contentful/branch/master/graph/badge.svg)](https://codecov.io/gh/labd/terraform-contentful) -[![license](https://img.shields.io/github/license/contentful-labs/terraform-contentful.svg)](https://github.com/labd/terraform-contentful/blob/master/LICENSE) +[![license](https://img.shields.io/github/license/labd/terraform-contentful.svg)](https://github.com/labd/terraform-contentful/blob/master/LICENSE) Terraform Provider for [Contentful's](https://www.contentful.com) Content Management API # About - [Contentful](https://www.contentful.com) provides a content infrastructure for digital teams to power content in websites, apps, and devices. Unlike a CMS, Contentful was built to integrate with the modern software stack. It offers a central hub for structured content, powerful management and delivery APIs, and a customizable web app that enable developers and content creators to ship digital products faster. [Terraform](https://www.terraform.io) is a tool for building, changing, and versioning infrastructure safely and efficiently. Terraform can manage existing and popular service providers as well as custom in-house solutions. @@ -15,10 +14,12 @@ Terraform Provider for [Contentful's](https://www.contentful.com) Content Manage Create, update and delete Contentful resources such as: - [x] Spaces -- [ ] Content Types +- [x] Content Types - [x] API Keys - [x] Webhooks -- [ ] Locales +- [x] Locales +- [x] Environments +- [ ] Organizations # Getting started @@ -51,6 +52,10 @@ Build the binary $ go build -o terraform-provider-contentful +*Or using make command* + + $ make build + Add it to your ~/.terraformrc (or %APPDATA%/terraform.rc for Windows) $ cat ~/.terraformrc @@ -70,7 +75,7 @@ Use the provider by creating a main.tf file with: Run the terraform plan - terraform plan -out=contentful.plan + $ terraform plan -out=contentful.plan Check the changes ``` @@ -99,6 +104,10 @@ Plan: 1 to add, 0 to change, 0 to destroy. ``` Apply the plan + + $ terraform apply + +Check the Terraform output for warnings and errors ``` contentful_space.test: Creating... default_locale: "" => "en" @@ -118,11 +127,15 @@ State path: ## Testing - TF_ACC=1 go test -v + $ TF_ACC=1 go test -v + +To enable higher verbose mode: + + $ TF_LOG=debug TF_ACC=1 go test -v -To enable higher verbose mode +For testing, you can also make use of the make command: - TF_LOG=debug TF_ACC=1 go test -v + $ make test-unit ## Documentation/References diff --git a/contentful/constants.go b/contentful/constants.go index 3beaa75..cff5289 100644 --- a/contentful/constants.go +++ b/contentful/constants.go @@ -1,19 +1,15 @@ package contentful import ( - "errors" "os" ) -// noinspection GoUnusedGlobalVariable var ( - baseURL = "https://api.contentful.com" - contentfulContentType = "application/vnd.contentful.management.v1+json" - spaceID = os.Getenv("SPACE_ID") - // User friendly errors we return - errorUnauthorized = errors.New("401 Unauthorized. Is the CMA token valid") - errorSpaceNotFound = errors.New("space not found") - errorOrganizationNotFound = errors.New("organization not found") - errorLocaleNotFound = errors.New("locale not found") - errorWebhookNotFound = errors.New("the webhook could not be found") + // Environment variables + spaceID = os.Getenv("SPACE_ID") + CMAToken = os.Getenv("CONTENTFUL_MANAGEMENT_TOKEN") + orgID = os.Getenv("CONTENTFUL_ORGANIZATION_ID") + + // Terraform configuration values + logBoolean = os.Getenv("TF_LOG") ) diff --git a/contentful/provider.go b/contentful/provider.go index bc930d0..55e5f66 100644 --- a/contentful/provider.go +++ b/contentful/provider.go @@ -1,14 +1,12 @@ package contentful import ( - "os" - "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/terraform" contentful "github.com/labd/contentful-go" ) -// Provider does shit +// Provider returns the Terraform Provider as a scheme and makes resources reachable func Provider() terraform.ResourceProvider { return &schema.Provider{ Schema: map[string]*schema.Schema{ @@ -31,16 +29,18 @@ func Provider() terraform.ResourceProvider { "contentful_apikey": resourceContentfulAPIKey(), "contentful_webhook": resourceContentfulWebhook(), "contentful_locale": resourceContentfulLocale(), + "contentful_environment": resourceContentfulEnvironment(), }, ConfigureFunc: providerConfigure, } } +// providerConfigure sets the configuration for the Terraform Provider func providerConfigure(d *schema.ResourceData) (interface{}, error) { cma := contentful.NewCMA(d.Get("cma_token").(string)) cma.SetOrganization(d.Get("organization_id").(string)) - if os.Getenv("TF_LOG") != "" { + if logBoolean != "" { cma.Debug = true } diff --git a/contentful/provider_test.go b/contentful/provider_test.go index bec87e8..44bdb5a 100644 --- a/contentful/provider_test.go +++ b/contentful/provider_test.go @@ -1,7 +1,6 @@ package contentful import ( - "os" "testing" "github.com/hashicorp/terraform/helper/schema" @@ -30,10 +29,10 @@ func TestProvider_impl(t *testing.T) { func testAccPreCheck(t *testing.T) { var cmaToken, organizationID string - if cmaToken = os.Getenv("CONTENTFUL_MANAGEMENT_TOKEN"); cmaToken == "" { + if cmaToken = CMAToken; cmaToken == "" { t.Fatal("CONTENTFUL_MANAGEMENT_TOKEN must set with a valid Contentful Content Management API Token for acceptance tests") } - if organizationID = os.Getenv("CONTENTFUL_ORGANIZATION_ID"); organizationID == "" { + if organizationID = orgID; organizationID == "" { t.Fatal("CONTENTFUL_ORGANIZATION_ID must set with a valid Contentful Organization ID for acceptance tests") } } diff --git a/contentful/resource_contentful_contenttype.go b/contentful/resource_contentful_contenttype.go index 8b90c63..59ebf4b 100644 --- a/contentful/resource_contentful_contenttype.go +++ b/contentful/resource_contentful_contenttype.go @@ -216,7 +216,7 @@ func resourceContentTypeUpdate(d *schema.ResourceData, m interface{}) (err error } // To remove a field from a content type 4 API calls need to be made. - // Ommit the removed fields and publish the new version of the content type, + // Omit the removed fields and publish the new version of the content type, // followed by the field removal and final publish. if err = client.ContentTypes.Upsert(spaceID, ct); err != nil { return err diff --git a/contentful/resource_contentful_environment.go b/contentful/resource_contentful_environment.go new file mode 100644 index 0000000..d6f35d6 --- /dev/null +++ b/contentful/resource_contentful_environment.go @@ -0,0 +1,120 @@ +package contentful + +import ( + "github.com/hashicorp/terraform/helper/schema" + contentful "github.com/labd/contentful-go" +) + +func resourceContentfulEnvironment() *schema.Resource { + return &schema.Resource{ + Create: resourceCreateEnvironment, + Read: resourceReadEnvironment, + Update: resourceUpdateEnvironment, + Delete: resourceDeleteEnvironment, + + Schema: map[string]*schema.Schema{ + "version": { + Type: schema.TypeInt, + Computed: true, + }, + "space_id": { + Type: schema.TypeString, + Required: true, + }, + "name": { + Type: schema.TypeString, + Required: true, + }, + }, + } +} + +func resourceCreateEnvironment(d *schema.ResourceData, m interface{}) (err error) { + client := m.(*contentful.Client) + + environment := &contentful.Environment{ + Name: d.Get("name").(string), + } + + err = client.Environments.Upsert(d.Get("space_id").(string), environment) + if err != nil { + return err + } + + if err := setEnvironmentProperties(d, environment); err != nil { + return err + } + + d.SetId(environment.Name) + + return nil +} + +func resourceUpdateEnvironment(d *schema.ResourceData, m interface{}) (err error) { + client := m.(*contentful.Client) + spaceID := d.Get("space_id").(string) + environmentID := d.Id() + + environment, err := client.Environments.Get(spaceID, environmentID) + if err != nil { + return err + } + + environment.Name = d.Get("name").(string) + + err = client.Environments.Upsert(spaceID, environment) + if err != nil { + return err + } + + if err := setEnvironmentProperties(d, environment); err != nil { + return err + } + + d.SetId(environment.Sys.ID) + + return nil +} + +func resourceReadEnvironment(d *schema.ResourceData, m interface{}) (err error) { + client := m.(*contentful.Client) + spaceID := d.Get("space_id").(string) + environmentID := d.Id() + + environment, err := client.Environments.Get(spaceID, environmentID) + if _, ok := err.(contentful.NotFoundError); ok { + d.SetId("") + return nil + } + + return setEnvironmentProperties(d, environment) +} + +func resourceDeleteEnvironment(d *schema.ResourceData, m interface{}) (err error) { + client := m.(*contentful.Client) + spaceID := d.Get("space_id").(string) + environmentID := d.Id() + + environment, err := client.Environments.Get(spaceID, environmentID) + if err != nil { + return err + } + + return client.Environments.Delete(spaceID, environment) +} + +func setEnvironmentProperties(d *schema.ResourceData, environment *contentful.Environment) error { + if err := d.Set("space_id", environment.Sys.Space.Sys.ID); err != nil { + return err + } + + if err := d.Set("version", environment.Sys.Version); err != nil { + return err + } + + if err := d.Set("name", environment.Name); err != nil { + return err + } + + return nil +} diff --git a/contentful/resource_contentful_environment_test.go b/contentful/resource_contentful_environment_test.go new file mode 100644 index 0000000..c707d6d --- /dev/null +++ b/contentful/resource_contentful_environment_test.go @@ -0,0 +1,125 @@ +package contentful + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + contentful "github.com/labd/contentful-go" +) + +func TestAccContentfulEnvironment_Basic(t *testing.T) { + var environment contentful.Environment + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccContentfulEnvironmentDestroy, + Steps: []resource.TestStep{ + { + Config: testAccContentfulEnvironmentConfig, + Check: resource.ComposeTestCheckFunc( + testAccCheckContentfulEnvironmentExists("contentful_environment.myenvironment", &environment), + testAccCheckContentfulEnvironmentAttributes(&environment, map[string]interface{}{ + "space_id": spaceID, + "name": "provider-test", + }), + ), + }, + { + Config: testAccContentfulEnvironmentUpdateConfig, + Check: resource.ComposeTestCheckFunc( + testAccCheckContentfulEnvironmentExists("contentful_environment.myenvironment", &environment), + testAccCheckContentfulEnvironmentAttributes(&environment, map[string]interface{}{ + "space_id": spaceID, + "name": "provider-test-updated", + }), + ), + }, + }, + }) +} + +func testAccCheckContentfulEnvironmentExists(n string, environment *contentful.Environment) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("not Found: %s", n) + } + + spaceID := rs.Primary.Attributes["space_id"] + if spaceID == "" { + return fmt.Errorf("no space_id is set") + } + + name := rs.Primary.Attributes["name"] + if name == "" { + return fmt.Errorf("no name is set") + } + + client := testAccProvider.Meta().(*contentful.Client) + + contentfulEnvironment, err := client.Environments.Get(spaceID, rs.Primary.ID) + if err != nil { + return err + } + + *environment = *contentfulEnvironment + + return nil + } +} + +func testAccCheckContentfulEnvironmentAttributes(environment *contentful.Environment, attrs map[string]interface{}) resource.TestCheckFunc { + return func(s *terraform.State) error { + name := attrs["name"].(string) + if environment.Name != name { + return fmt.Errorf("locale name does not match: %s, %s", environment.Name, name) + } + + return nil + } +} + +func testAccContentfulEnvironmentDestroy(s *terraform.State) error { + for _, rs := range s.RootModule().Resources { + if rs.Type != "contentful_locale" { + continue + } + spaceID := rs.Primary.Attributes["space_id"] + if spaceID == "" { + return fmt.Errorf("no space_id is set") + } + + localeID := rs.Primary.ID + if localeID == "" { + return fmt.Errorf("no locale ID is set") + } + + client := testAccProvider.Meta().(*contentful.Client) + + _, err := client.Locales.Get(spaceID, localeID) + if _, ok := err.(contentful.NotFoundError); ok { + return nil + } + + return fmt.Errorf("locale still exists with id: %s", localeID) + } + + return nil +} + +var testAccContentfulEnvironmentConfig = ` +resource "contentful_environment" "myenvironment" { + space_id = "` + spaceID + `" + name = "provider-test" +} +` + +var testAccContentfulEnvironmentUpdateConfig = ` +resource "contentful_environment" "myenvironment" { + space_id = "` + spaceID + `" + name = "provider-test-updated" +} +` diff --git a/go.mod b/go.mod index f56f7b6..574b785 100644 --- a/go.mod +++ b/go.mod @@ -4,5 +4,5 @@ go 1.14 require ( github.com/hashicorp/terraform v0.12.24 - github.com/labd/contentful-go v0.4.1-0.20200420081834-f20ec0d2853f + github.com/labd/contentful-go v0.4.1-0.20200422125935-8ec49e6fa941 ) diff --git a/tools/test.sh b/tools/test.sh deleted file mode 100755 index f2234f1..0000000 --- a/tools/test.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env bash -set -e - -rm coverage.txt || true -touch coverage.txt - -for d in $(go list ./... | grep -v /vendor/); do - TF_ACC=1 go test -v -coverprofile=profile.out -covermode=count "$d" - - if [ -f profile.out ]; then - cat profile.out >> coverage.txt - rm profile.out - fi -done - -# to make `go tool cover -html=coverage.txt` happy -# remove the lines starting with mode -# remove the empty lines -sed -i'' -e '/^\s*$/d' coverage.txt -echo "$(awk '!/^mode:/ || !f++' coverage.txt)" > coverage.txt From ad5bf8b42c8f15ccc5cf44e51ef15d1be1994c09 Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Wed, 6 May 2020 17:41:29 +0200 Subject: [PATCH 067/192] Added support for entries. Created the entries resource. The entries can be created, updated and deleted. The archiving and publishing is also added into the resource, keep in mind that a resource can only be deleted when unpublished. --- contentful/provider.go | 1 + .../resource_contentful_contenttype_test.go | 14 +- contentful/resource_contentful_entry.go | 206 +++++++++++++++++ contentful/resource_contentful_entry_test.go | 207 ++++++++++++++++++ go.mod | 2 +- 5 files changed, 422 insertions(+), 8 deletions(-) create mode 100644 contentful/resource_contentful_entry.go create mode 100644 contentful/resource_contentful_entry_test.go diff --git a/contentful/provider.go b/contentful/provider.go index 55e5f66..19d95b9 100644 --- a/contentful/provider.go +++ b/contentful/provider.go @@ -30,6 +30,7 @@ func Provider() terraform.ResourceProvider { "contentful_webhook": resourceContentfulWebhook(), "contentful_locale": resourceContentfulLocale(), "contentful_environment": resourceContentfulEnvironment(), + "contentful_entry": resourceContentfulEntry(), }, ConfigureFunc: providerConfigure, } diff --git a/contentful/resource_contentful_contenttype_test.go b/contentful/resource_contentful_contenttype_test.go index 298624a..68d30cc 100644 --- a/contentful/resource_contentful_contenttype_test.go +++ b/contentful/resource_contentful_contenttype_test.go @@ -18,17 +18,17 @@ func TestAccContentfulContentType_Basic(t *testing.T) { { Config: testAccContentfulContentTypeConfig, Check: resource.TestCheckResourceAttr( - "contentful_contenttype.mycontenttype", "name", "TF Acc Test CT 1"), + "contentful_contenttype.mycontenttype", "name", "tf_test1"), }, { Config: testAccContentfulContentTypeUpdateConfig, Check: resource.TestCheckResourceAttr( - "contentful_contenttype.mycontenttype", "name", "TF Acc Test CT name change"), + "contentful_contenttype.mycontenttype", "name", "tf_test1"), }, { Config: testAccContentfulContentTypeLinkConfig, Check: resource.TestCheckResourceAttr( - "contentful_contenttype.mylinked_contenttype", "name", "TF Acc Test Linked CT"), + "contentful_contenttype.mylinked_contenttype", "name", "tf_linked"), }, }, }) @@ -91,7 +91,7 @@ func testAccCheckContentfulContentTypeDestroy(s *terraform.State) (err error) { var testAccContentfulContentTypeConfig = ` resource "contentful_contenttype" "mycontenttype" { space_id = "` + spaceID + `" - name = "TF Acc Test CT 1" + name = "tf_test1" description = "Terraform Acc Test Content Type" display_field = "field1" field { @@ -118,7 +118,7 @@ resource "contentful_contenttype" "mycontenttype" { var testAccContentfulContentTypeUpdateConfig = ` resource "contentful_contenttype" "mycontenttype" { space_id = "` + spaceID + `" - name = "TF Acc Test CT name change" + name = "tf_test1" description = "Terraform Acc Test Content Type description change" display_field = "field1" field { @@ -145,7 +145,7 @@ resource "contentful_contenttype" "mycontenttype" { var testAccContentfulContentTypeLinkConfig = ` resource "contentful_contenttype" "mycontenttype" { space_id = "` + spaceID + `" - name = "TF Acc Test CT name change" + name = "tf_test1" description = "Terraform Acc Test Content Type description change" display_field = "field1" field { @@ -170,7 +170,7 @@ resource "contentful_contenttype" "mycontenttype" { resource "contentful_contenttype" "mylinked_contenttype" { space_id = "` + spaceID + `" - name = "TF Acc Test Linked CT" + name = "tf_linked" description = "Terraform Acc Test Content Type with links" display_field = "asset_field" field { diff --git a/contentful/resource_contentful_entry.go b/contentful/resource_contentful_entry.go new file mode 100644 index 0000000..fd35500 --- /dev/null +++ b/contentful/resource_contentful_entry.go @@ -0,0 +1,206 @@ +package contentful + +import ( + "github.com/hashicorp/terraform/helper/schema" + contentful "github.com/labd/contentful-go" +) + +func resourceContentfulEntry() *schema.Resource { + return &schema.Resource{ + Create: resourceCreateEntry, + Read: resourceReadEntry, + Update: resourceUpdateEntry, + Delete: resourceDeleteEntry, + + Schema: map[string]*schema.Schema{ + "entry_id": { + Type: schema.TypeString, + Required: true, + }, + "version": { + Type: schema.TypeInt, + Computed: true, + }, + "space_id": { + Type: schema.TypeString, + Required: true, + }, + "contenttype_id": { + Type: schema.TypeString, + Required: true, + }, + "locale": { + Type: schema.TypeString, + Required: true, + }, + "field": { + Type: schema.TypeList, + Required: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Required: true, + }, + "content": { + Type: schema.TypeString, + Required: true, + }, + "locale": { + Type: schema.TypeString, + Required: true, + }, + }, + }, + }, + "published": { + Type: schema.TypeBool, + Required: true, + }, + "archived": { + Type: schema.TypeBool, + Required: true, + }, + }, + } +} + +func resourceCreateEntry(d *schema.ResourceData, m interface{}) (err error) { + client := m.(*contentful.Client) + + fieldProperties := map[string]interface{}{} + rawField := d.Get("field").([]interface{}) + for i := 0; i < len(rawField); i++ { + field := rawField[i].(map[string]interface{}) + fieldProperties[field["id"].(string)] = map[string]interface{}{} + fieldProperties[field["id"].(string)].(map[string]interface{})[field["locale"].(string)] = field["content"].(string) + } + + entry := &contentful.Entry{ + Locale: d.Get("locale").(string), + Fields: fieldProperties, + Sys: &contentful.Sys{ + ID: d.Get("entry_id").(string), + }, + } + + err = client.Entries.Upsert(d.Get("space_id").(string), d.Get("contenttype_id").(string), entry) + if err != nil { + return err + } + + err = setEntryState(d, m) + if err != nil { + return err + } + + if err := setEntryProperties(d, entry); err != nil { + return err + } + + d.SetId(entry.Sys.ID) + return nil +} + +func resourceUpdateEntry(d *schema.ResourceData, m interface{}) (err error) { + client := m.(*contentful.Client) + spaceID := d.Get("space_id").(string) + entryID := d.Id() + + entry, err := client.Entries.Get(spaceID, entryID) + if err != nil { + return err + } + + fieldProperties := map[string]interface{}{} + rawField := d.Get("field").([]interface{}) + for i := 0; i < len(rawField); i++ { + field := rawField[i].(map[string]interface{}) + fieldProperties[field["id"].(string)] = map[string]interface{}{} + fieldProperties[field["id"].(string)].(map[string]interface{})[field["locale"].(string)] = field["content"].(string) + } + + entry.Fields = fieldProperties + entry.Locale = d.Get("locale").(string) + + err = client.Entries.Upsert(d.Get("space_id").(string), d.Get("contenttype_id").(string), entry) + if err != nil { + return err + } + + if err := setEntryState(d, m); err != nil { + return err + } + + if err := setEntryProperties(d, entry); err != nil { + return err + } + d.SetId(entry.Sys.ID) + + return nil +} + +func setEntryState(d *schema.ResourceData, m interface{}) (err error) { + client := m.(*contentful.Client) + spaceID := d.Get("space_id").(string) + entryID := d.Id() + + entry, _ := client.Entries.Get(spaceID, entryID) + + if d.Get("published").(bool) && entry.Sys.PublishedAt == "" { + err = client.Entries.Publish(spaceID, entry) + } else if d.Get("published").(bool) && entry.Sys.PublishedAt != "" { + err = client.Entries.Unpublish(spaceID, entry) + } + + if d.Get("archived").(bool) && entry.Sys.ArchivedAt == "" { + err = client.Entries.Publish(spaceID, entry) + } else if d.Get("archived").(bool) && entry.Sys.ArchivedAt != "" { + err = client.Entries.Unpublish(spaceID, entry) + } + + return nil +} + +func resourceReadEntry(d *schema.ResourceData, m interface{}) (err error) { + client := m.(*contentful.Client) + spaceID := d.Get("space_id").(string) + entryID := d.Id() + + entry, err := client.Entries.Get(spaceID, entryID) + if _, ok := err.(contentful.NotFoundError); ok { + d.SetId("") + return nil + } + + return setEntryProperties(d, entry) +} + +func resourceDeleteEntry(d *schema.ResourceData, m interface{}) (err error) { + client := m.(*contentful.Client) + spaceID := d.Get("space_id").(string) + entryID := d.Id() + + _, err = client.Entries.Get(spaceID, entryID) + if err != nil { + return err + } + + return client.Entries.Delete(spaceID, entryID) +} + +func setEntryProperties(d *schema.ResourceData, entry *contentful.Entry) error { + if err := d.Set("space_id", entry.Sys.Space.Sys.ID); err != nil { + return err + } + + if err := d.Set("version", entry.Sys.Version); err != nil { + return err + } + + if err := d.Set("contenttype_id", entry.Sys.ContentType.Sys.ID); err != nil { + return err + } + + return nil +} diff --git a/contentful/resource_contentful_entry_test.go b/contentful/resource_contentful_entry_test.go new file mode 100644 index 0000000..a98b796 --- /dev/null +++ b/contentful/resource_contentful_entry_test.go @@ -0,0 +1,207 @@ +package contentful + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + contentful "github.com/labd/contentful-go" +) + +func TestAccContentfulEntry_Basic(t *testing.T) { + var entry contentful.Entry + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccContentfulEntryDestroy, + Steps: []resource.TestStep{ + { + Config: testAccContentfulEntryConfig, + Check: resource.ComposeTestCheckFunc( + testAccCheckContentfulEntryExists("contentful_entry.myentry", &entry), + testAccCheckContentfulEntryAttributes(&entry, map[string]interface{}{ + "space_id": spaceID, + }), + ), + }, + { + Config: testAccContentfulEntryUpdateConfig, + Check: resource.ComposeTestCheckFunc( + testAccCheckContentfulEntryExists("contentful_entry.myentry", &entry), + testAccCheckContentfulEntryAttributes(&entry, map[string]interface{}{ + "space_id": spaceID, + }), + ), + }, + }, + }) +} + +func testAccCheckContentfulEntryExists(n string, entry *contentful.Entry) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("not Found: %s", n) + } + + spaceID := rs.Primary.Attributes["space_id"] + if spaceID == "" { + return fmt.Errorf("no space_id is set") + } + + contenttypeID := rs.Primary.Attributes["contenttype_id"] + if contenttypeID == "" { + return fmt.Errorf("no contenttype_id is set") + } + + client := testAccProvider.Meta().(*contentful.Client) + + contentfulEntry, err := client.Entries.Get(spaceID, rs.Primary.ID) + if err != nil { + return err + } + + *entry = *contentfulEntry + + return nil + } +} + +func testAccCheckContentfulEntryAttributes(entry *contentful.Entry, attrs map[string]interface{}) resource.TestCheckFunc { + return func(s *terraform.State) error { + + spaceIDCheck := attrs["space_id"].(string) + if entry.Sys.Space.Sys.ID != spaceIDCheck { + return fmt.Errorf("space id does not match: %s, %s", entry.Sys.Space.Sys.ID, spaceIDCheck) + } + + return nil + } +} + +func testAccContentfulEntryDestroy(s *terraform.State) error { + for _, rs := range s.RootModule().Resources { + if rs.Type != "contentful_entry" { + continue + } + + // get space id from resource data + spaceID := rs.Primary.Attributes["space_id"] + if spaceID == "" { + return fmt.Errorf("no space_id is set") + } + + // check webhook resource id + if rs.Primary.ID == "" { + return fmt.Errorf("no entry ID is set") + } + + // sdk client + client := testAccProvider.Meta().(*contentful.Client) + + entry, _ := client.Entries.Get(spaceID, rs.Primary.ID) + if entry == nil { + return nil + } + + return fmt.Errorf("entry still exists with id: %s", rs.Primary.ID) + } + + return nil +} + +var testAccContentfulEntryConfig = ` +resource "contentful_contenttype" "mycontenttype" { + space_id = "` + spaceID + `" + name = "tf_test_1" + description = "Terraform Acc Test Content Type" + display_field = "field1" + field { + disabled = false + id = "field1" + localized = false + name = "Field 1" + omitted = false + required = true + type = "Text" + } + field { + disabled = false + id = "field2" + localized = false + name = "Field 2" + omitted = false + required = true + type = "Text" + } +} + +resource "contentful_entry" "myentry" { + entry_id = "mytestentry" + space_id = "` + spaceID + `" + contenttype_id = "tf_test_1" + locale = "en-US" + field { + id = "field1" + content = "Hello, World!" + locale = "en-US" + } + field { + id = "field2" + content = "Bacon is healthy!" + locale = "en-US" + } + published = true + archived = false + depends_on = [contentful_contenttype.mycontenttype] +} +` + +var testAccContentfulEntryUpdateConfig = ` +resource "contentful_contenttype" "mycontenttype" { + space_id = "` + spaceID + `" + name = "tf_test_1" + description = "Terraform Acc Test Content Type" + display_field = "field1" + field { + disabled = false + id = "field1" + localized = false + name = "Field 1" + omitted = false + required = true + type = "Text" + } + field { + disabled = false + id = "field2" + localized = false + name = "Field 2" + omitted = false + required = true + type = "Text" + } +} + +resource "contentful_entry" "myentry" { + entry_id = "mytestentry" + space_id = "` + spaceID + `" + contenttype_id = "tf_test_1" + locale = "en-US" + field { + id = "field1" + content = "Hello, World!" + locale = "en-US" + } + field { + id = "field2" + content = "Bacon is healthy!" + locale = "en-US" + } + published = true + archived = false + depends_on = [contentful_contenttype.mycontenttype] +} +` diff --git a/go.mod b/go.mod index 574b785..c04fc29 100644 --- a/go.mod +++ b/go.mod @@ -4,5 +4,5 @@ go 1.14 require ( github.com/hashicorp/terraform v0.12.24 - github.com/labd/contentful-go v0.4.1-0.20200422125935-8ec49e6fa941 + github.com/labd/contentful-go v0.4.1-0.20200506145415-ef08d6413074 ) From aeec4135a885a7c0c7d8a89709c9130ada327a0d Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Fri, 8 May 2020 16:33:25 +0200 Subject: [PATCH 068/192] Added support for assets. Created the new assets resource. This resource is used to add files and images to the Contentful environment. --- contentful/provider.go | 1 + contentful/resource_contentful_asset.go | 344 +++++++++++++++++++ contentful/resource_contentful_asset_test.go | 158 +++++++++ contentful/resource_contentful_entry.go | 8 +- go.mod | 2 +- 5 files changed, 508 insertions(+), 5 deletions(-) create mode 100644 contentful/resource_contentful_asset.go create mode 100644 contentful/resource_contentful_asset_test.go diff --git a/contentful/provider.go b/contentful/provider.go index 19d95b9..e9e2224 100644 --- a/contentful/provider.go +++ b/contentful/provider.go @@ -31,6 +31,7 @@ func Provider() terraform.ResourceProvider { "contentful_locale": resourceContentfulLocale(), "contentful_environment": resourceContentfulEnvironment(), "contentful_entry": resourceContentfulEntry(), + "contentful_asset": resourceContentfulAsset(), }, ConfigureFunc: providerConfigure, } diff --git a/contentful/resource_contentful_asset.go b/contentful/resource_contentful_asset.go new file mode 100644 index 0000000..d03def7 --- /dev/null +++ b/contentful/resource_contentful_asset.go @@ -0,0 +1,344 @@ +package contentful + +import ( + "github.com/hashicorp/terraform/helper/schema" + contentful "github.com/labd/contentful-go" +) + +func resourceContentfulAsset() *schema.Resource { + return &schema.Resource{ + Create: resourceCreateAsset, + Read: resourceReadAsset, + Update: resourceUpdateAsset, + Delete: resourceDeleteAsset, + + Schema: map[string]*schema.Schema{ + "asset_id": { + Type: schema.TypeString, + Required: true, + }, + "version": { + Type: schema.TypeInt, + Computed: true, + }, + "locale": { + Type: schema.TypeString, + Required: true, + }, + "space_id": { + Type: schema.TypeString, + Required: true, + }, + "fields": { + Type: schema.TypeList, + Required: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "title": { + Type: schema.TypeList, + Required: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "content": { + Type: schema.TypeString, + Required: true, + }, + "locale": { + Type: schema.TypeString, + Required: true, + }, + }, + }, + }, + "description": { + Type: schema.TypeList, + Required: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "content": { + Type: schema.TypeString, + Required: true, + }, + "locale": { + Type: schema.TypeString, + Required: true, + }, + }, + }, + }, + "file": { + Type: schema.TypeMap, + Required: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "url": { + Type: schema.TypeString, + Optional: true, + }, + "upload": { + Type: schema.TypeString, + Optional: true, + }, + "details": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "size": { + Type: schema.TypeInt, + Required: true, + }, + "image": { + Type: schema.TypeSet, + Required: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "width": { + Type: schema.TypeInt, + Required: true, + }, + "height": { + Type: schema.TypeInt, + Required: true, + }, + }, + }, + }, + }, + }, + }, + "fileName": { + Type: schema.TypeString, + Required: true, + }, + "contentType": { + Type: schema.TypeString, + Required: true, + }, + }, + }, + }, + }, + }, + }, + "published": { + Type: schema.TypeBool, + Required: true, + }, + "archived": { + Type: schema.TypeBool, + Required: true, + }, + }, + } +} + +func resourceCreateAsset(d *schema.ResourceData, m interface{}) (err error) { + client := m.(*contentful.Client) + + fields := d.Get("fields").([]interface{})[0].(map[string]interface{}) + + localizedTitle := map[string]string{} + rawTitle := fields["title"].([]interface{}) + for i := 0; i < len(rawTitle); i++ { + field := rawTitle[i].(map[string]interface{}) + localizedTitle[field["locale"].(string)] = field["content"].(string) + } + + localizedDescription := map[string]string{} + rawDescription := fields["description"].([]interface{}) + for i := 0; i < len(rawDescription); i++ { + field := rawDescription[i].(map[string]interface{}) + localizedDescription[field["locale"].(string)] = field["content"].(string) + } + + file := fields["file"].(map[string]interface{}) + + asset := &contentful.Asset{ + Sys: &contentful.Sys{ + ID: d.Get("asset_id").(string), + Version: 0, + }, + Locale: d.Get("locale").(string), + Fields: &contentful.AssetFields{ + Title: localizedTitle, + Description: localizedDescription, + File: map[string]*contentful.File{ + d.Get("locale").(string): { + FileName: file["fileName"].(string), + ContentType: file["contentType"].(string), + UploadURL: file["upload"].(string), + }, + }, + }, + } + + if url, ok := file["url"].(string); ok { + asset.Fields.File[d.Get("locale").(string)].URL = url + } + + if details, ok := file["fileDetails"].(*contentful.FileDetails); ok { + asset.Fields.File[d.Get("locale").(string)].Details = details + } + + err = client.Assets.Upsert(d.Get("space_id").(string), asset) + if err != nil { + return err + } + + err = client.Assets.Process(d.Get("space_id").(string), asset) + if err != nil { + return err + } + + err = setAssetState(d, m) + if err != nil { + return err + } + + if err := setAssetProperties(d, asset); err != nil { + return err + } + + d.SetId(asset.Sys.ID) + return nil +} + +func resourceUpdateAsset(d *schema.ResourceData, m interface{}) (err error) { + client := m.(*contentful.Client) + spaceID := d.Get("space_id").(string) + assetID := d.Id() + + asset, err := client.Assets.Get(spaceID, assetID) + if err != nil { + return err + } + + fields := d.Get("fields").([]interface{})[0].(map[string]interface{}) + + localizedTitle := map[string]string{} + rawTitle := fields["title"].([]interface{}) + for i := 0; i < len(rawTitle); i++ { + field := rawTitle[i].(map[string]interface{}) + localizedTitle[field["locale"].(string)] = field["content"].(string) + } + + localizedDescription := map[string]string{} + rawDescription := fields["description"].([]interface{}) + for i := 0; i < len(rawDescription); i++ { + field := rawDescription[i].(map[string]interface{}) + localizedDescription[field["locale"].(string)] = field["content"].(string) + } + + file := fields["file"].(map[string]interface{}) + + asset = &contentful.Asset{ + Sys: &contentful.Sys{ + ID: d.Get("asset_id").(string), + Version: d.Get("version").(int), + }, + Locale: d.Get("locale").(string), + Fields: &contentful.AssetFields{ + Title: localizedTitle, + Description: localizedDescription, + File: map[string]*contentful.File{ + d.Get("locale").(string): { + FileName: file["fileName"].(string), + ContentType: file["contentType"].(string), + UploadURL: file["upload"].(string), + }, + }, + }, + } + + if url, ok := file["url"].(string); ok { + asset.Fields.File[d.Get("locale").(string)].URL = url + } + + if details, ok := file["fileDetails"].(*contentful.FileDetails); ok { + asset.Fields.File[d.Get("locale").(string)].Details = details + } + + err = client.Assets.Upsert(d.Get("space_id").(string), asset) + if err != nil { + return err + } + + err = client.Assets.Process(d.Get("space_id").(string), asset) + if err != nil { + return err + } + + err = setAssetState(d, m) + if err != nil { + return err + } + + if err := setAssetProperties(d, asset); err != nil { + return err + } + + d.SetId(asset.Sys.ID) + return nil +} + +func setAssetState(d *schema.ResourceData, m interface{}) (err error) { + client := m.(*contentful.Client) + spaceID := d.Get("space_id").(string) + assetID := d.Id() + + asset, _ := client.Assets.Get(spaceID, assetID) + + if d.Get("published").(bool) && asset.Sys.PublishedAt == "" { + err = client.Assets.Publish(spaceID, asset) + } else if !d.Get("published").(bool) && asset.Sys.PublishedAt != "" { + err = client.Assets.Unpublish(spaceID, asset) + } + + if d.Get("archived").(bool) && asset.Sys.ArchivedAt == "" { + err = client.Assets.Archive(spaceID, asset) + } else if !d.Get("archived").(bool) && asset.Sys.ArchivedAt != "" { + err = client.Assets.Unarchive(spaceID, asset) + } + + return nil +} + +func resourceReadAsset(d *schema.ResourceData, m interface{}) (err error) { + client := m.(*contentful.Client) + spaceID := d.Get("space_id").(string) + assetID := d.Id() + + asset, err := client.Assets.Get(spaceID, assetID) + if _, ok := err.(contentful.NotFoundError); ok { + d.SetId("") + return nil + } + + return setAssetProperties(d, asset) +} + +func resourceDeleteAsset(d *schema.ResourceData, m interface{}) (err error) { + client := m.(*contentful.Client) + spaceID := d.Get("space_id").(string) + assetID := d.Id() + + asset, err := client.Assets.Get(spaceID, assetID) + if err != nil { + return err + } + + return client.Assets.Delete(spaceID, asset) +} + +func setAssetProperties(d *schema.ResourceData, asset *contentful.Asset) error { + if err := d.Set("space_id", asset.Sys.Space.Sys.ID); err != nil { + return err + } + + if err := d.Set("version", asset.Sys.Version); err != nil { + return err + } + + return nil +} diff --git a/contentful/resource_contentful_asset_test.go b/contentful/resource_contentful_asset_test.go new file mode 100644 index 0000000..576e75c --- /dev/null +++ b/contentful/resource_contentful_asset_test.go @@ -0,0 +1,158 @@ +package contentful + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + contentful "github.com/labd/contentful-go" +) + +func TestAccContentfulAsset_Basic(t *testing.T) { + var asset contentful.Asset + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccContentfulAssetDestroy, + Steps: []resource.TestStep{ + { + Config: testAccContentfulAssetConfig, + Check: resource.ComposeTestCheckFunc( + testAccCheckContentfulAssetExists("contentful_asset.myasset", &asset), + testAccCheckContentfulAssetAttributes(&asset, map[string]interface{}{ + "space_id": spaceID, + }), + ), + }, + { + Config: testAccContentfulAssetUpdateConfig, + Check: resource.ComposeTestCheckFunc( + testAccCheckContentfulAssetExists("contentful_asset.myasset", &asset), + testAccCheckContentfulAssetAttributes(&asset, map[string]interface{}{ + "space_id": spaceID, + }), + ), + }, + }, + }) +} + +func testAccCheckContentfulAssetExists(n string, asset *contentful.Asset) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("not Found: %s", n) + } + + spaceID := rs.Primary.Attributes["space_id"] + if spaceID == "" { + return fmt.Errorf("no space_id is set") + } + + client := testAccProvider.Meta().(*contentful.Client) + + contentfulAsset, err := client.Assets.Get(spaceID, rs.Primary.ID) + if err != nil { + return err + } + + *asset = *contentfulAsset + + return nil + } +} + +func testAccCheckContentfulAssetAttributes(asset *contentful.Asset, attrs map[string]interface{}) resource.TestCheckFunc { + return func(s *terraform.State) error { + + spaceIDCheck := attrs["space_id"].(string) + if asset.Sys.Space.Sys.ID != spaceIDCheck { + return fmt.Errorf("space id does not match: %s, %s", asset.Sys.Space.Sys.ID, spaceIDCheck) + } + + return nil + } +} + +func testAccContentfulAssetDestroy(s *terraform.State) error { + for _, rs := range s.RootModule().Resources { + if rs.Type != "contentful_entry" { + continue + } + + // get space id from resource data + spaceID := rs.Primary.Attributes["space_id"] + if spaceID == "" { + return fmt.Errorf("no space_id is set") + } + + // check webhook resource id + if rs.Primary.ID == "" { + return fmt.Errorf("no asset ID is set") + } + + // sdk client + client := testAccProvider.Meta().(*contentful.Client) + + asset, _ := client.Assets.Get(spaceID, rs.Primary.ID) + if asset == nil { + return nil + } + + return fmt.Errorf("asset still exists with id: %s", rs.Primary.ID) + } + + return nil +} + +var testAccContentfulAssetConfig = ` +resource "contentful_asset" "myasset" { + asset_id = "test_asset" + locale = "en-US" + space_id = "` + spaceID + `" + fields { + title { + locale = "en-US" + content = "Asset title" + } + description { + locale = "en-US" + content = "Asset description" + } + file = { + upload = "https://images.ctfassets.net/fo9twyrwpveg/2VQx7vz73aMEYi20MMgCk0/66e502115b1f1f973a944b4bd2cc536f/IC-1H_Modern_Stack_Website.svg" + fileName = "example.jpeg" + contentType = "image/jpeg" + } + } + published = true + archived = false +} +` + +var testAccContentfulAssetUpdateConfig = ` +resource "contentful_asset" "myasset" { + asset_id = "test_asset" + locale = "en-US" + space_id = "` + spaceID + `" + fields { + title { + locale = "en-US" + content = "Updated asset title" + } + description { + locale = "en-US" + content = "Updated asset description" + } + file = { + upload = "https://images.ctfassets.net/fo9twyrwpveg/2VQx7vz73aMEYi20MMgCk0/66e502115b1f1f973a944b4bd2cc536f/IC-1H_Modern_Stack_Website.svg" + fileName = "example.jpeg" + contentType = "image/jpeg" + } + } + published = true + archived = false +} +` diff --git a/contentful/resource_contentful_entry.go b/contentful/resource_contentful_entry.go index fd35500..baa3105 100644 --- a/contentful/resource_contentful_entry.go +++ b/contentful/resource_contentful_entry.go @@ -149,14 +149,14 @@ func setEntryState(d *schema.ResourceData, m interface{}) (err error) { if d.Get("published").(bool) && entry.Sys.PublishedAt == "" { err = client.Entries.Publish(spaceID, entry) - } else if d.Get("published").(bool) && entry.Sys.PublishedAt != "" { + } else if !d.Get("published").(bool) && entry.Sys.PublishedAt != "" { err = client.Entries.Unpublish(spaceID, entry) } if d.Get("archived").(bool) && entry.Sys.ArchivedAt == "" { - err = client.Entries.Publish(spaceID, entry) - } else if d.Get("archived").(bool) && entry.Sys.ArchivedAt != "" { - err = client.Entries.Unpublish(spaceID, entry) + err = client.Entries.Archive(spaceID, entry) + } else if !d.Get("archived").(bool) && entry.Sys.ArchivedAt != "" { + err = client.Entries.Unarchive(spaceID, entry) } return nil diff --git a/go.mod b/go.mod index c04fc29..0e73d39 100644 --- a/go.mod +++ b/go.mod @@ -4,5 +4,5 @@ go 1.14 require ( github.com/hashicorp/terraform v0.12.24 - github.com/labd/contentful-go v0.4.1-0.20200506145415-ef08d6413074 + github.com/labd/contentful-go v0.4.1-0.20200508125900-edd2d77b81af ) From 58617b1c5243188970722974ea028b96e2be3145 Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Mon, 11 May 2020 11:17:51 +0200 Subject: [PATCH 069/192] Fixed versioning bug. When creating and updating assets and entries, the publish and unpublish calls also updates the version property. This resulted in a version mismatch error. --- README.md | 3 +- contentful/resource_contentful_asset.go | 41 ++++++++++++-------- contentful/resource_contentful_asset_test.go | 2 +- contentful/resource_contentful_entry.go | 31 ++++++++------- contentful/resource_contentful_entry_test.go | 2 +- 5 files changed, 45 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index 89d9180..a8b9bdf 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,8 @@ Create, update and delete Contentful resources such as: - [x] Webhooks - [x] Locales - [x] Environments -- [ ] Organizations +- [x] Entries +- [x] Assets # Getting started diff --git a/contentful/resource_contentful_asset.go b/contentful/resource_contentful_asset.go index d03def7..71e57e4 100644 --- a/contentful/resource_contentful_asset.go +++ b/contentful/resource_contentful_asset.go @@ -167,7 +167,6 @@ func resourceCreateAsset(d *schema.ResourceData, m interface{}) (err error) { d.Get("locale").(string): { FileName: file["fileName"].(string), ContentType: file["contentType"].(string), - UploadURL: file["upload"].(string), }, }, }, @@ -177,6 +176,10 @@ func resourceCreateAsset(d *schema.ResourceData, m interface{}) (err error) { asset.Fields.File[d.Get("locale").(string)].URL = url } + if upload, ok := file["upload"].(string); ok { + asset.Fields.File[d.Get("locale").(string)].UploadURL = upload + } + if details, ok := file["fileDetails"].(*contentful.FileDetails); ok { asset.Fields.File[d.Get("locale").(string)].Details = details } @@ -191,17 +194,18 @@ func resourceCreateAsset(d *schema.ResourceData, m interface{}) (err error) { return err } - err = setAssetState(d, m) - if err != nil { + d.SetId(asset.Sys.ID) + + if err := setAssetProperties(d, asset); err != nil { return err } - if err := setAssetProperties(d, asset); err != nil { + err = setAssetState(d, m) + if err != nil { return err } - d.SetId(asset.Sys.ID) - return nil + return err } func resourceUpdateAsset(d *schema.ResourceData, m interface{}) (err error) { @@ -269,17 +273,18 @@ func resourceUpdateAsset(d *schema.ResourceData, m interface{}) (err error) { return err } - err = setAssetState(d, m) - if err != nil { + d.SetId(asset.Sys.ID) + + if err := setAssetProperties(d, asset); err != nil { return err } - if err := setAssetProperties(d, asset); err != nil { + err = setAssetState(d, m) + if err != nil { return err } - d.SetId(asset.Sys.ID) - return nil + return err } func setAssetState(d *schema.ResourceData, m interface{}) (err error) { @@ -301,7 +306,11 @@ func setAssetState(d *schema.ResourceData, m interface{}) (err error) { err = client.Assets.Unarchive(spaceID, asset) } - return nil + if err := setAssetProperties(d, asset); err != nil { + return err + } + + return err } func resourceReadAsset(d *schema.ResourceData, m interface{}) (err error) { @@ -331,14 +340,14 @@ func resourceDeleteAsset(d *schema.ResourceData, m interface{}) (err error) { return client.Assets.Delete(spaceID, asset) } -func setAssetProperties(d *schema.ResourceData, asset *contentful.Asset) error { - if err := d.Set("space_id", asset.Sys.Space.Sys.ID); err != nil { +func setAssetProperties(d *schema.ResourceData, asset *contentful.Asset) (err error) { + if err = d.Set("space_id", asset.Sys.Space.Sys.ID); err != nil { return err } - if err := d.Set("version", asset.Sys.Version); err != nil { + if err = d.Set("version", asset.Sys.Version); err != nil { return err } - return nil + return err } diff --git a/contentful/resource_contentful_asset_test.go b/contentful/resource_contentful_asset_test.go index 576e75c..b198af3 100644 --- a/contentful/resource_contentful_asset_test.go +++ b/contentful/resource_contentful_asset_test.go @@ -152,7 +152,7 @@ resource "contentful_asset" "myasset" { contentType = "image/jpeg" } } - published = true + published = false archived = false } ` diff --git a/contentful/resource_contentful_entry.go b/contentful/resource_contentful_entry.go index baa3105..7c1e109 100644 --- a/contentful/resource_contentful_entry.go +++ b/contentful/resource_contentful_entry.go @@ -89,17 +89,17 @@ func resourceCreateEntry(d *schema.ResourceData, m interface{}) (err error) { return err } - err = setEntryState(d, m) - if err != nil { + if err := setEntryProperties(d, entry); err != nil { return err } - if err := setEntryProperties(d, entry); err != nil { + d.SetId(entry.Sys.ID) + + if err := setEntryState(d, m); err != nil { return err } - d.SetId(entry.Sys.ID) - return nil + return err } func resourceUpdateEntry(d *schema.ResourceData, m interface{}) (err error) { @@ -128,16 +128,17 @@ func resourceUpdateEntry(d *schema.ResourceData, m interface{}) (err error) { return err } - if err := setEntryState(d, m); err != nil { + d.SetId(entry.Sys.ID) + + if err := setEntryProperties(d, entry); err != nil { return err } - if err := setEntryProperties(d, entry); err != nil { + if err := setEntryState(d, m); err != nil { return err } - d.SetId(entry.Sys.ID) - return nil + return err } func setEntryState(d *schema.ResourceData, m interface{}) (err error) { @@ -159,7 +160,7 @@ func setEntryState(d *schema.ResourceData, m interface{}) (err error) { err = client.Entries.Unarchive(spaceID, entry) } - return nil + return err } func resourceReadEntry(d *schema.ResourceData, m interface{}) (err error) { @@ -189,18 +190,18 @@ func resourceDeleteEntry(d *schema.ResourceData, m interface{}) (err error) { return client.Entries.Delete(spaceID, entryID) } -func setEntryProperties(d *schema.ResourceData, entry *contentful.Entry) error { - if err := d.Set("space_id", entry.Sys.Space.Sys.ID); err != nil { +func setEntryProperties(d *schema.ResourceData, entry *contentful.Entry) (err error) { + if err = d.Set("space_id", entry.Sys.Space.Sys.ID); err != nil { return err } - if err := d.Set("version", entry.Sys.Version); err != nil { + if err = d.Set("version", entry.Sys.Version); err != nil { return err } - if err := d.Set("contenttype_id", entry.Sys.ContentType.Sys.ID); err != nil { + if err = d.Set("contenttype_id", entry.Sys.ContentType.Sys.ID); err != nil { return err } - return nil + return err } diff --git a/contentful/resource_contentful_entry_test.go b/contentful/resource_contentful_entry_test.go index a98b796..6c589a7 100644 --- a/contentful/resource_contentful_entry_test.go +++ b/contentful/resource_contentful_entry_test.go @@ -200,7 +200,7 @@ resource "contentful_entry" "myentry" { content = "Bacon is healthy!" locale = "en-US" } - published = true + published = false archived = false depends_on = [contentful_contenttype.mycontenttype] } From fbb9be24711b2333c2a74dc4dfb85efbb43ab6f4 Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Mon, 11 May 2020 11:46:03 +0200 Subject: [PATCH 070/192] Fixed early-return bug. Setting properties call seems to throw an error when called with Docker. Removed return should fix this problem. --- contentful/resource_contentful_asset.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/contentful/resource_contentful_asset.go b/contentful/resource_contentful_asset.go index 71e57e4..af34fd9 100644 --- a/contentful/resource_contentful_asset.go +++ b/contentful/resource_contentful_asset.go @@ -306,9 +306,7 @@ func setAssetState(d *schema.ResourceData, m interface{}) (err error) { err = client.Assets.Unarchive(spaceID, asset) } - if err := setAssetProperties(d, asset); err != nil { - return err - } + err = setAssetProperties(d, asset) return err } From 92c857d404ef6748deddae29212caab54f75eba3 Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Mon, 11 May 2020 12:39:28 +0200 Subject: [PATCH 071/192] Features/assets (#6) * Added support for assets. Created the new assets resource. This resource is used to add files and images to the Contentful environment. * Fixed versioning bug. When creating and updating assets and entries, the publish and unpublish calls also updates the version property. This resulted in a version mismatch error. * Fixed early-return bug. Setting properties call seems to throw an error when called with Docker. Removed return should fix this problem. Co-authored-by: Kantoor --- README.md | 3 +- contentful/provider.go | 1 + contentful/resource_contentful_asset.go | 351 +++++++++++++++++++ contentful/resource_contentful_asset_test.go | 158 +++++++++ contentful/resource_contentful_entry.go | 39 ++- contentful/resource_contentful_entry_test.go | 2 +- go.mod | 2 +- 7 files changed, 534 insertions(+), 22 deletions(-) create mode 100644 contentful/resource_contentful_asset.go create mode 100644 contentful/resource_contentful_asset_test.go diff --git a/README.md b/README.md index 89d9180..a8b9bdf 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,8 @@ Create, update and delete Contentful resources such as: - [x] Webhooks - [x] Locales - [x] Environments -- [ ] Organizations +- [x] Entries +- [x] Assets # Getting started diff --git a/contentful/provider.go b/contentful/provider.go index 19d95b9..e9e2224 100644 --- a/contentful/provider.go +++ b/contentful/provider.go @@ -31,6 +31,7 @@ func Provider() terraform.ResourceProvider { "contentful_locale": resourceContentfulLocale(), "contentful_environment": resourceContentfulEnvironment(), "contentful_entry": resourceContentfulEntry(), + "contentful_asset": resourceContentfulAsset(), }, ConfigureFunc: providerConfigure, } diff --git a/contentful/resource_contentful_asset.go b/contentful/resource_contentful_asset.go new file mode 100644 index 0000000..af34fd9 --- /dev/null +++ b/contentful/resource_contentful_asset.go @@ -0,0 +1,351 @@ +package contentful + +import ( + "github.com/hashicorp/terraform/helper/schema" + contentful "github.com/labd/contentful-go" +) + +func resourceContentfulAsset() *schema.Resource { + return &schema.Resource{ + Create: resourceCreateAsset, + Read: resourceReadAsset, + Update: resourceUpdateAsset, + Delete: resourceDeleteAsset, + + Schema: map[string]*schema.Schema{ + "asset_id": { + Type: schema.TypeString, + Required: true, + }, + "version": { + Type: schema.TypeInt, + Computed: true, + }, + "locale": { + Type: schema.TypeString, + Required: true, + }, + "space_id": { + Type: schema.TypeString, + Required: true, + }, + "fields": { + Type: schema.TypeList, + Required: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "title": { + Type: schema.TypeList, + Required: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "content": { + Type: schema.TypeString, + Required: true, + }, + "locale": { + Type: schema.TypeString, + Required: true, + }, + }, + }, + }, + "description": { + Type: schema.TypeList, + Required: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "content": { + Type: schema.TypeString, + Required: true, + }, + "locale": { + Type: schema.TypeString, + Required: true, + }, + }, + }, + }, + "file": { + Type: schema.TypeMap, + Required: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "url": { + Type: schema.TypeString, + Optional: true, + }, + "upload": { + Type: schema.TypeString, + Optional: true, + }, + "details": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "size": { + Type: schema.TypeInt, + Required: true, + }, + "image": { + Type: schema.TypeSet, + Required: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "width": { + Type: schema.TypeInt, + Required: true, + }, + "height": { + Type: schema.TypeInt, + Required: true, + }, + }, + }, + }, + }, + }, + }, + "fileName": { + Type: schema.TypeString, + Required: true, + }, + "contentType": { + Type: schema.TypeString, + Required: true, + }, + }, + }, + }, + }, + }, + }, + "published": { + Type: schema.TypeBool, + Required: true, + }, + "archived": { + Type: schema.TypeBool, + Required: true, + }, + }, + } +} + +func resourceCreateAsset(d *schema.ResourceData, m interface{}) (err error) { + client := m.(*contentful.Client) + + fields := d.Get("fields").([]interface{})[0].(map[string]interface{}) + + localizedTitle := map[string]string{} + rawTitle := fields["title"].([]interface{}) + for i := 0; i < len(rawTitle); i++ { + field := rawTitle[i].(map[string]interface{}) + localizedTitle[field["locale"].(string)] = field["content"].(string) + } + + localizedDescription := map[string]string{} + rawDescription := fields["description"].([]interface{}) + for i := 0; i < len(rawDescription); i++ { + field := rawDescription[i].(map[string]interface{}) + localizedDescription[field["locale"].(string)] = field["content"].(string) + } + + file := fields["file"].(map[string]interface{}) + + asset := &contentful.Asset{ + Sys: &contentful.Sys{ + ID: d.Get("asset_id").(string), + Version: 0, + }, + Locale: d.Get("locale").(string), + Fields: &contentful.AssetFields{ + Title: localizedTitle, + Description: localizedDescription, + File: map[string]*contentful.File{ + d.Get("locale").(string): { + FileName: file["fileName"].(string), + ContentType: file["contentType"].(string), + }, + }, + }, + } + + if url, ok := file["url"].(string); ok { + asset.Fields.File[d.Get("locale").(string)].URL = url + } + + if upload, ok := file["upload"].(string); ok { + asset.Fields.File[d.Get("locale").(string)].UploadURL = upload + } + + if details, ok := file["fileDetails"].(*contentful.FileDetails); ok { + asset.Fields.File[d.Get("locale").(string)].Details = details + } + + err = client.Assets.Upsert(d.Get("space_id").(string), asset) + if err != nil { + return err + } + + err = client.Assets.Process(d.Get("space_id").(string), asset) + if err != nil { + return err + } + + d.SetId(asset.Sys.ID) + + if err := setAssetProperties(d, asset); err != nil { + return err + } + + err = setAssetState(d, m) + if err != nil { + return err + } + + return err +} + +func resourceUpdateAsset(d *schema.ResourceData, m interface{}) (err error) { + client := m.(*contentful.Client) + spaceID := d.Get("space_id").(string) + assetID := d.Id() + + asset, err := client.Assets.Get(spaceID, assetID) + if err != nil { + return err + } + + fields := d.Get("fields").([]interface{})[0].(map[string]interface{}) + + localizedTitle := map[string]string{} + rawTitle := fields["title"].([]interface{}) + for i := 0; i < len(rawTitle); i++ { + field := rawTitle[i].(map[string]interface{}) + localizedTitle[field["locale"].(string)] = field["content"].(string) + } + + localizedDescription := map[string]string{} + rawDescription := fields["description"].([]interface{}) + for i := 0; i < len(rawDescription); i++ { + field := rawDescription[i].(map[string]interface{}) + localizedDescription[field["locale"].(string)] = field["content"].(string) + } + + file := fields["file"].(map[string]interface{}) + + asset = &contentful.Asset{ + Sys: &contentful.Sys{ + ID: d.Get("asset_id").(string), + Version: d.Get("version").(int), + }, + Locale: d.Get("locale").(string), + Fields: &contentful.AssetFields{ + Title: localizedTitle, + Description: localizedDescription, + File: map[string]*contentful.File{ + d.Get("locale").(string): { + FileName: file["fileName"].(string), + ContentType: file["contentType"].(string), + UploadURL: file["upload"].(string), + }, + }, + }, + } + + if url, ok := file["url"].(string); ok { + asset.Fields.File[d.Get("locale").(string)].URL = url + } + + if details, ok := file["fileDetails"].(*contentful.FileDetails); ok { + asset.Fields.File[d.Get("locale").(string)].Details = details + } + + err = client.Assets.Upsert(d.Get("space_id").(string), asset) + if err != nil { + return err + } + + err = client.Assets.Process(d.Get("space_id").(string), asset) + if err != nil { + return err + } + + d.SetId(asset.Sys.ID) + + if err := setAssetProperties(d, asset); err != nil { + return err + } + + err = setAssetState(d, m) + if err != nil { + return err + } + + return err +} + +func setAssetState(d *schema.ResourceData, m interface{}) (err error) { + client := m.(*contentful.Client) + spaceID := d.Get("space_id").(string) + assetID := d.Id() + + asset, _ := client.Assets.Get(spaceID, assetID) + + if d.Get("published").(bool) && asset.Sys.PublishedAt == "" { + err = client.Assets.Publish(spaceID, asset) + } else if !d.Get("published").(bool) && asset.Sys.PublishedAt != "" { + err = client.Assets.Unpublish(spaceID, asset) + } + + if d.Get("archived").(bool) && asset.Sys.ArchivedAt == "" { + err = client.Assets.Archive(spaceID, asset) + } else if !d.Get("archived").(bool) && asset.Sys.ArchivedAt != "" { + err = client.Assets.Unarchive(spaceID, asset) + } + + err = setAssetProperties(d, asset) + + return err +} + +func resourceReadAsset(d *schema.ResourceData, m interface{}) (err error) { + client := m.(*contentful.Client) + spaceID := d.Get("space_id").(string) + assetID := d.Id() + + asset, err := client.Assets.Get(spaceID, assetID) + if _, ok := err.(contentful.NotFoundError); ok { + d.SetId("") + return nil + } + + return setAssetProperties(d, asset) +} + +func resourceDeleteAsset(d *schema.ResourceData, m interface{}) (err error) { + client := m.(*contentful.Client) + spaceID := d.Get("space_id").(string) + assetID := d.Id() + + asset, err := client.Assets.Get(spaceID, assetID) + if err != nil { + return err + } + + return client.Assets.Delete(spaceID, asset) +} + +func setAssetProperties(d *schema.ResourceData, asset *contentful.Asset) (err error) { + if err = d.Set("space_id", asset.Sys.Space.Sys.ID); err != nil { + return err + } + + if err = d.Set("version", asset.Sys.Version); err != nil { + return err + } + + return err +} diff --git a/contentful/resource_contentful_asset_test.go b/contentful/resource_contentful_asset_test.go new file mode 100644 index 0000000..b198af3 --- /dev/null +++ b/contentful/resource_contentful_asset_test.go @@ -0,0 +1,158 @@ +package contentful + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + contentful "github.com/labd/contentful-go" +) + +func TestAccContentfulAsset_Basic(t *testing.T) { + var asset contentful.Asset + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccContentfulAssetDestroy, + Steps: []resource.TestStep{ + { + Config: testAccContentfulAssetConfig, + Check: resource.ComposeTestCheckFunc( + testAccCheckContentfulAssetExists("contentful_asset.myasset", &asset), + testAccCheckContentfulAssetAttributes(&asset, map[string]interface{}{ + "space_id": spaceID, + }), + ), + }, + { + Config: testAccContentfulAssetUpdateConfig, + Check: resource.ComposeTestCheckFunc( + testAccCheckContentfulAssetExists("contentful_asset.myasset", &asset), + testAccCheckContentfulAssetAttributes(&asset, map[string]interface{}{ + "space_id": spaceID, + }), + ), + }, + }, + }) +} + +func testAccCheckContentfulAssetExists(n string, asset *contentful.Asset) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("not Found: %s", n) + } + + spaceID := rs.Primary.Attributes["space_id"] + if spaceID == "" { + return fmt.Errorf("no space_id is set") + } + + client := testAccProvider.Meta().(*contentful.Client) + + contentfulAsset, err := client.Assets.Get(spaceID, rs.Primary.ID) + if err != nil { + return err + } + + *asset = *contentfulAsset + + return nil + } +} + +func testAccCheckContentfulAssetAttributes(asset *contentful.Asset, attrs map[string]interface{}) resource.TestCheckFunc { + return func(s *terraform.State) error { + + spaceIDCheck := attrs["space_id"].(string) + if asset.Sys.Space.Sys.ID != spaceIDCheck { + return fmt.Errorf("space id does not match: %s, %s", asset.Sys.Space.Sys.ID, spaceIDCheck) + } + + return nil + } +} + +func testAccContentfulAssetDestroy(s *terraform.State) error { + for _, rs := range s.RootModule().Resources { + if rs.Type != "contentful_entry" { + continue + } + + // get space id from resource data + spaceID := rs.Primary.Attributes["space_id"] + if spaceID == "" { + return fmt.Errorf("no space_id is set") + } + + // check webhook resource id + if rs.Primary.ID == "" { + return fmt.Errorf("no asset ID is set") + } + + // sdk client + client := testAccProvider.Meta().(*contentful.Client) + + asset, _ := client.Assets.Get(spaceID, rs.Primary.ID) + if asset == nil { + return nil + } + + return fmt.Errorf("asset still exists with id: %s", rs.Primary.ID) + } + + return nil +} + +var testAccContentfulAssetConfig = ` +resource "contentful_asset" "myasset" { + asset_id = "test_asset" + locale = "en-US" + space_id = "` + spaceID + `" + fields { + title { + locale = "en-US" + content = "Asset title" + } + description { + locale = "en-US" + content = "Asset description" + } + file = { + upload = "https://images.ctfassets.net/fo9twyrwpveg/2VQx7vz73aMEYi20MMgCk0/66e502115b1f1f973a944b4bd2cc536f/IC-1H_Modern_Stack_Website.svg" + fileName = "example.jpeg" + contentType = "image/jpeg" + } + } + published = true + archived = false +} +` + +var testAccContentfulAssetUpdateConfig = ` +resource "contentful_asset" "myasset" { + asset_id = "test_asset" + locale = "en-US" + space_id = "` + spaceID + `" + fields { + title { + locale = "en-US" + content = "Updated asset title" + } + description { + locale = "en-US" + content = "Updated asset description" + } + file = { + upload = "https://images.ctfassets.net/fo9twyrwpveg/2VQx7vz73aMEYi20MMgCk0/66e502115b1f1f973a944b4bd2cc536f/IC-1H_Modern_Stack_Website.svg" + fileName = "example.jpeg" + contentType = "image/jpeg" + } + } + published = false + archived = false +} +` diff --git a/contentful/resource_contentful_entry.go b/contentful/resource_contentful_entry.go index fd35500..7c1e109 100644 --- a/contentful/resource_contentful_entry.go +++ b/contentful/resource_contentful_entry.go @@ -89,17 +89,17 @@ func resourceCreateEntry(d *schema.ResourceData, m interface{}) (err error) { return err } - err = setEntryState(d, m) - if err != nil { + if err := setEntryProperties(d, entry); err != nil { return err } - if err := setEntryProperties(d, entry); err != nil { + d.SetId(entry.Sys.ID) + + if err := setEntryState(d, m); err != nil { return err } - d.SetId(entry.Sys.ID) - return nil + return err } func resourceUpdateEntry(d *schema.ResourceData, m interface{}) (err error) { @@ -128,16 +128,17 @@ func resourceUpdateEntry(d *schema.ResourceData, m interface{}) (err error) { return err } - if err := setEntryState(d, m); err != nil { + d.SetId(entry.Sys.ID) + + if err := setEntryProperties(d, entry); err != nil { return err } - if err := setEntryProperties(d, entry); err != nil { + if err := setEntryState(d, m); err != nil { return err } - d.SetId(entry.Sys.ID) - return nil + return err } func setEntryState(d *schema.ResourceData, m interface{}) (err error) { @@ -149,17 +150,17 @@ func setEntryState(d *schema.ResourceData, m interface{}) (err error) { if d.Get("published").(bool) && entry.Sys.PublishedAt == "" { err = client.Entries.Publish(spaceID, entry) - } else if d.Get("published").(bool) && entry.Sys.PublishedAt != "" { + } else if !d.Get("published").(bool) && entry.Sys.PublishedAt != "" { err = client.Entries.Unpublish(spaceID, entry) } if d.Get("archived").(bool) && entry.Sys.ArchivedAt == "" { - err = client.Entries.Publish(spaceID, entry) - } else if d.Get("archived").(bool) && entry.Sys.ArchivedAt != "" { - err = client.Entries.Unpublish(spaceID, entry) + err = client.Entries.Archive(spaceID, entry) + } else if !d.Get("archived").(bool) && entry.Sys.ArchivedAt != "" { + err = client.Entries.Unarchive(spaceID, entry) } - return nil + return err } func resourceReadEntry(d *schema.ResourceData, m interface{}) (err error) { @@ -189,18 +190,18 @@ func resourceDeleteEntry(d *schema.ResourceData, m interface{}) (err error) { return client.Entries.Delete(spaceID, entryID) } -func setEntryProperties(d *schema.ResourceData, entry *contentful.Entry) error { - if err := d.Set("space_id", entry.Sys.Space.Sys.ID); err != nil { +func setEntryProperties(d *schema.ResourceData, entry *contentful.Entry) (err error) { + if err = d.Set("space_id", entry.Sys.Space.Sys.ID); err != nil { return err } - if err := d.Set("version", entry.Sys.Version); err != nil { + if err = d.Set("version", entry.Sys.Version); err != nil { return err } - if err := d.Set("contenttype_id", entry.Sys.ContentType.Sys.ID); err != nil { + if err = d.Set("contenttype_id", entry.Sys.ContentType.Sys.ID); err != nil { return err } - return nil + return err } diff --git a/contentful/resource_contentful_entry_test.go b/contentful/resource_contentful_entry_test.go index a98b796..6c589a7 100644 --- a/contentful/resource_contentful_entry_test.go +++ b/contentful/resource_contentful_entry_test.go @@ -200,7 +200,7 @@ resource "contentful_entry" "myentry" { content = "Bacon is healthy!" locale = "en-US" } - published = true + published = false archived = false depends_on = [contentful_contenttype.mycontenttype] } diff --git a/go.mod b/go.mod index c04fc29..0e73d39 100644 --- a/go.mod +++ b/go.mod @@ -4,5 +4,5 @@ go 1.14 require ( github.com/hashicorp/terraform v0.12.24 - github.com/labd/contentful-go v0.4.1-0.20200506145415-ef08d6413074 + github.com/labd/contentful-go v0.4.1-0.20200508125900-edd2d77b81af ) From 702ceb071155126964a7af972ef7704eec4dc1ed Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Wed, 13 May 2020 10:49:01 +0200 Subject: [PATCH 072/192] Fixed optional fields of asset. Update was missing optional fields, also added field uploadFrom. This is required for uploads --- contentful/resource_contentful_asset.go | 19 +++++++++++++++++-- go.mod | 2 +- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/contentful/resource_contentful_asset.go b/contentful/resource_contentful_asset.go index af34fd9..d48036a 100644 --- a/contentful/resource_contentful_asset.go +++ b/contentful/resource_contentful_asset.go @@ -107,9 +107,13 @@ func resourceContentfulAsset() *schema.Resource { }, }, }, + "uploadFrom": { + Type: schema.TypeString, + Computed: true, + }, "fileName": { Type: schema.TypeString, - Required: true, + Computed: true, }, "contentType": { Type: schema.TypeString, @@ -184,6 +188,10 @@ func resourceCreateAsset(d *schema.ResourceData, m interface{}) (err error) { asset.Fields.File[d.Get("locale").(string)].Details = details } + if uploadFrom, ok := file["uploadFrom"].(string); ok { + asset.Fields.File[d.Get("locale").(string)].UploadFrom.Sys.ID = uploadFrom + } + err = client.Assets.Upsert(d.Get("space_id").(string), asset) if err != nil { return err @@ -249,7 +257,6 @@ func resourceUpdateAsset(d *schema.ResourceData, m interface{}) (err error) { d.Get("locale").(string): { FileName: file["fileName"].(string), ContentType: file["contentType"].(string), - UploadURL: file["upload"].(string), }, }, }, @@ -259,10 +266,18 @@ func resourceUpdateAsset(d *schema.ResourceData, m interface{}) (err error) { asset.Fields.File[d.Get("locale").(string)].URL = url } + if upload, ok := file["upload"].(string); ok { + asset.Fields.File[d.Get("locale").(string)].UploadURL = upload + } + if details, ok := file["fileDetails"].(*contentful.FileDetails); ok { asset.Fields.File[d.Get("locale").(string)].Details = details } + if uploadFrom, ok := file["uploadFrom"].(string); ok { + asset.Fields.File[d.Get("locale").(string)].UploadFrom.Sys.ID = uploadFrom + } + err = client.Assets.Upsert(d.Get("space_id").(string), asset) if err != nil { return err diff --git a/go.mod b/go.mod index 0e73d39..a01d7c9 100644 --- a/go.mod +++ b/go.mod @@ -4,5 +4,5 @@ go 1.14 require ( github.com/hashicorp/terraform v0.12.24 - github.com/labd/contentful-go v0.4.1-0.20200508125900-edd2d77b81af + github.com/labd/contentful-go v0.4.1-0.20200512094354-cc45b8138ed9 ) From 2e9c03ad7f8e948f6a22e3b67720236ffb9c7104 Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Wed, 13 May 2020 10:50:40 +0200 Subject: [PATCH 073/192] Added uploads service. Uploads can be used to set local files to the Contentful environment. --- contentful/provider.go | 1 + contentful/resource_contentful_upload.go | 148 ++++++++++++++++++ contentful/resource_contentful_upload_test.go | 110 +++++++++++++ 3 files changed, 259 insertions(+) create mode 100644 contentful/resource_contentful_upload.go create mode 100644 contentful/resource_contentful_upload_test.go diff --git a/contentful/provider.go b/contentful/provider.go index e9e2224..f357e24 100644 --- a/contentful/provider.go +++ b/contentful/provider.go @@ -32,6 +32,7 @@ func Provider() terraform.ResourceProvider { "contentful_environment": resourceContentfulEnvironment(), "contentful_entry": resourceContentfulEntry(), "contentful_asset": resourceContentfulAsset(), + "contentful_upload": resourceContentfulUpload(), }, ConfigureFunc: providerConfigure, } diff --git a/contentful/resource_contentful_upload.go b/contentful/resource_contentful_upload.go new file mode 100644 index 0000000..fceb740 --- /dev/null +++ b/contentful/resource_contentful_upload.go @@ -0,0 +1,148 @@ +package contentful + +import ( + "encoding/json" + "fmt" + "github.com/hashicorp/terraform/helper/schema" + contentful "github.com/labd/contentful-go" +) + +func resourceContentfulUpload() *schema.Resource { + return &schema.Resource{ + Create: resourceCreateUpload, + Read: resourceReadUpload, + Update: nil, + Delete: resourceDeleteUpload, + + Schema: map[string]*schema.Schema{ + "space_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "file_path": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "asset_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "locale": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "title": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "description": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + }, + } +} + +func resourceCreateUpload(d *schema.ResourceData, m interface{}) (err error) { + uploadClient := contentful.NewResourceClient(CMAToken) + uploadClient.SetOrganization(orgID) + client := m.(*contentful.Client) + + upload := contentful.Resource{} + + fmt.Println(d.Get("space_id").(string)) + fmt.Println(d.Get("file_path").(string)) + + response := uploadClient.Resources.Create(d.Get("space_id").(string), d.Get("file_path").(string)) + err = json.Unmarshal([]byte(response.Error()), &upload) + + d.SetId(upload.Sys.ID) + + if err := setUploadProperties(d, &upload); err != nil { + return err + } + + asset := &contentful.Asset{ + Sys: &contentful.Sys{ + ID: d.Get("asset_id").(string), + Version: 0, + }, + Locale: d.Get("locale").(string), + Fields: &contentful.AssetFields{ + Title: map[string]string{ + d.Get("locale").(string): d.Get("title").(string), + }, + Description: map[string]string{ + d.Get("locale").(string): d.Get("description").(string), + }, + File: map[string]*contentful.File{ + d.Get("locale").(string): { + UploadFrom: &contentful.UploadFrom{ + Sys: &contentful.Sys{ + ID: "upload.Sys.ID", + LinkType: "Upload", + }, + }, + }, + }, + }, + } + + err = client.Assets.Upsert(d.Get("space_id").(string), asset) + if err != nil { + return err + } + + err = client.Assets.Process(d.Get("space_id").(string), asset) + if err != nil { + return err + } + + err = client.Assets.Publish(spaceID, asset) + if err != nil { + return err + } + + return err +} + +func resourceReadUpload(d *schema.ResourceData, m interface{}) (err error) { + client := m.(*contentful.Client) + spaceID := d.Get("space_id").(string) + uploadID := d.Id() + + upload, err := client.Resources.Get(spaceID, uploadID) + if _, ok := err.(contentful.NotFoundError); ok { + d.SetId("") + return err + } + + return setUploadProperties(d, upload) +} + +func resourceDeleteUpload(d *schema.ResourceData, m interface{}) (err error) { + client := m.(*contentful.Client) + spaceID := d.Get("space_id").(string) + uploadID := d.Id() + + _, err = client.Resources.Get(spaceID, uploadID) + if err != nil { + return err + } + + return client.Resources.Delete(spaceID, uploadID) +} + +func setUploadProperties(d *schema.ResourceData, resource *contentful.Resource) (err error) { + if err = d.Set("space_id", resource.Sys.Space.Sys.ID); err != nil { + return err + } + + return err +} diff --git a/contentful/resource_contentful_upload_test.go b/contentful/resource_contentful_upload_test.go new file mode 100644 index 0000000..047e71a --- /dev/null +++ b/contentful/resource_contentful_upload_test.go @@ -0,0 +1,110 @@ +package contentful + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + contentful "github.com/labd/contentful-go" +) + +func TestAccContentfulUpload_Basic(t *testing.T) { + var upload contentful.Resource + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccContentfulUploadDestroy, + Steps: []resource.TestStep{ + { + Config: testAccContentfulUploadConfig, + Check: resource.ComposeTestCheckFunc( + testAccCheckContentfulUploadExists("contentful_asset.myupload", &upload), + testAccCheckContentfulUploadAttributes(&upload, map[string]interface{}{ + "space_id": spaceID, + }), + ), + }, + }, + }) +} + +func testAccCheckContentfulUploadExists(n string, upload *contentful.Resource) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("not Found: %s", n) + } + + spaceID := rs.Primary.Attributes["space_id"] + if spaceID == "" { + return fmt.Errorf("no space_id is set") + } + + client := testAccProvider.Meta().(*contentful.Client) + + contentfulAsset, err := client.Resources.Get(spaceID, rs.Primary.ID) + if err != nil { + return err + } + + *upload = *contentfulAsset + + return nil + } +} + +func testAccCheckContentfulUploadAttributes(upload *contentful.Resource, attrs map[string]interface{}) resource.TestCheckFunc { + return func(s *terraform.State) error { + + spaceIDCheck := attrs["space_id"].(string) + if upload.Sys.Space.Sys.ID != spaceIDCheck { + return fmt.Errorf("space id does not match: %s, %s", upload.Sys.Space.Sys.ID, spaceIDCheck) + } + + return nil + } +} + +func testAccContentfulUploadDestroy(s *terraform.State) error { + for _, rs := range s.RootModule().Resources { + if rs.Type != "contentful_entry" { + continue + } + + // get space id from resource data + spaceID := rs.Primary.Attributes["space_id"] + if spaceID == "" { + return fmt.Errorf("no space_id is set") + } + + // check webhook resource id + if rs.Primary.ID == "" { + return fmt.Errorf("no asset ID is set") + } + + // sdk client + client := testAccProvider.Meta().(*contentful.Client) + + asset, _ := client.Assets.Get(spaceID, rs.Primary.ID) + if asset == nil { + return nil + } + + return fmt.Errorf("asset still exists with id: %s", rs.Primary.ID) + } + + return nil +} + +var testAccContentfulUploadConfig = ` +resource "contentful_upload" "myupload" { + space_id = "` + spaceID + `" + file_path = "/home/kantoor/go/src/github.com/labd/terraform-contentful/local/upload_test.png" + asset_id = "upload_test" + locale = "en-US" + title = "This is an asset" + description = "Uploaded asset!" +} +` From 52c736a6c407cf826b273bef2da1774b6d3bb43c Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Wed, 13 May 2020 11:00:09 +0200 Subject: [PATCH 074/192] Optional fields Added missing optional fields and the uploadFrom field which is required by the upload resource. --- contentful/resource_contentful_asset.go | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/contentful/resource_contentful_asset.go b/contentful/resource_contentful_asset.go index af34fd9..d48036a 100644 --- a/contentful/resource_contentful_asset.go +++ b/contentful/resource_contentful_asset.go @@ -107,9 +107,13 @@ func resourceContentfulAsset() *schema.Resource { }, }, }, + "uploadFrom": { + Type: schema.TypeString, + Computed: true, + }, "fileName": { Type: schema.TypeString, - Required: true, + Computed: true, }, "contentType": { Type: schema.TypeString, @@ -184,6 +188,10 @@ func resourceCreateAsset(d *schema.ResourceData, m interface{}) (err error) { asset.Fields.File[d.Get("locale").(string)].Details = details } + if uploadFrom, ok := file["uploadFrom"].(string); ok { + asset.Fields.File[d.Get("locale").(string)].UploadFrom.Sys.ID = uploadFrom + } + err = client.Assets.Upsert(d.Get("space_id").(string), asset) if err != nil { return err @@ -249,7 +257,6 @@ func resourceUpdateAsset(d *schema.ResourceData, m interface{}) (err error) { d.Get("locale").(string): { FileName: file["fileName"].(string), ContentType: file["contentType"].(string), - UploadURL: file["upload"].(string), }, }, }, @@ -259,10 +266,18 @@ func resourceUpdateAsset(d *schema.ResourceData, m interface{}) (err error) { asset.Fields.File[d.Get("locale").(string)].URL = url } + if upload, ok := file["upload"].(string); ok { + asset.Fields.File[d.Get("locale").(string)].UploadURL = upload + } + if details, ok := file["fileDetails"].(*contentful.FileDetails); ok { asset.Fields.File[d.Get("locale").(string)].Details = details } + if uploadFrom, ok := file["uploadFrom"].(string); ok { + asset.Fields.File[d.Get("locale").(string)].UploadFrom.Sys.ID = uploadFrom + } + err = client.Assets.Upsert(d.Get("space_id").(string), asset) if err != nil { return err From 82c55d477ea80c0e0ec6bf3ff6315a699035e8f1 Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Wed, 13 May 2020 11:02:12 +0200 Subject: [PATCH 075/192] Uploads resource to different branch. --- contentful/resource_contentful_upload.go | 148 ------------------ contentful/resource_contentful_upload_test.go | 110 ------------- 2 files changed, 258 deletions(-) delete mode 100644 contentful/resource_contentful_upload.go delete mode 100644 contentful/resource_contentful_upload_test.go diff --git a/contentful/resource_contentful_upload.go b/contentful/resource_contentful_upload.go deleted file mode 100644 index fceb740..0000000 --- a/contentful/resource_contentful_upload.go +++ /dev/null @@ -1,148 +0,0 @@ -package contentful - -import ( - "encoding/json" - "fmt" - "github.com/hashicorp/terraform/helper/schema" - contentful "github.com/labd/contentful-go" -) - -func resourceContentfulUpload() *schema.Resource { - return &schema.Resource{ - Create: resourceCreateUpload, - Read: resourceReadUpload, - Update: nil, - Delete: resourceDeleteUpload, - - Schema: map[string]*schema.Schema{ - "space_id": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - }, - "file_path": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - }, - "asset_id": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - }, - "locale": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - }, - "title": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - }, - "description": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - }, - }, - } -} - -func resourceCreateUpload(d *schema.ResourceData, m interface{}) (err error) { - uploadClient := contentful.NewResourceClient(CMAToken) - uploadClient.SetOrganization(orgID) - client := m.(*contentful.Client) - - upload := contentful.Resource{} - - fmt.Println(d.Get("space_id").(string)) - fmt.Println(d.Get("file_path").(string)) - - response := uploadClient.Resources.Create(d.Get("space_id").(string), d.Get("file_path").(string)) - err = json.Unmarshal([]byte(response.Error()), &upload) - - d.SetId(upload.Sys.ID) - - if err := setUploadProperties(d, &upload); err != nil { - return err - } - - asset := &contentful.Asset{ - Sys: &contentful.Sys{ - ID: d.Get("asset_id").(string), - Version: 0, - }, - Locale: d.Get("locale").(string), - Fields: &contentful.AssetFields{ - Title: map[string]string{ - d.Get("locale").(string): d.Get("title").(string), - }, - Description: map[string]string{ - d.Get("locale").(string): d.Get("description").(string), - }, - File: map[string]*contentful.File{ - d.Get("locale").(string): { - UploadFrom: &contentful.UploadFrom{ - Sys: &contentful.Sys{ - ID: "upload.Sys.ID", - LinkType: "Upload", - }, - }, - }, - }, - }, - } - - err = client.Assets.Upsert(d.Get("space_id").(string), asset) - if err != nil { - return err - } - - err = client.Assets.Process(d.Get("space_id").(string), asset) - if err != nil { - return err - } - - err = client.Assets.Publish(spaceID, asset) - if err != nil { - return err - } - - return err -} - -func resourceReadUpload(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Client) - spaceID := d.Get("space_id").(string) - uploadID := d.Id() - - upload, err := client.Resources.Get(spaceID, uploadID) - if _, ok := err.(contentful.NotFoundError); ok { - d.SetId("") - return err - } - - return setUploadProperties(d, upload) -} - -func resourceDeleteUpload(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Client) - spaceID := d.Get("space_id").(string) - uploadID := d.Id() - - _, err = client.Resources.Get(spaceID, uploadID) - if err != nil { - return err - } - - return client.Resources.Delete(spaceID, uploadID) -} - -func setUploadProperties(d *schema.ResourceData, resource *contentful.Resource) (err error) { - if err = d.Set("space_id", resource.Sys.Space.Sys.ID); err != nil { - return err - } - - return err -} diff --git a/contentful/resource_contentful_upload_test.go b/contentful/resource_contentful_upload_test.go deleted file mode 100644 index 047e71a..0000000 --- a/contentful/resource_contentful_upload_test.go +++ /dev/null @@ -1,110 +0,0 @@ -package contentful - -import ( - "fmt" - "testing" - - "github.com/hashicorp/terraform/helper/resource" - "github.com/hashicorp/terraform/terraform" - contentful "github.com/labd/contentful-go" -) - -func TestAccContentfulUpload_Basic(t *testing.T) { - var upload contentful.Resource - - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccContentfulUploadDestroy, - Steps: []resource.TestStep{ - { - Config: testAccContentfulUploadConfig, - Check: resource.ComposeTestCheckFunc( - testAccCheckContentfulUploadExists("contentful_asset.myupload", &upload), - testAccCheckContentfulUploadAttributes(&upload, map[string]interface{}{ - "space_id": spaceID, - }), - ), - }, - }, - }) -} - -func testAccCheckContentfulUploadExists(n string, upload *contentful.Resource) resource.TestCheckFunc { - return func(s *terraform.State) error { - rs, ok := s.RootModule().Resources[n] - if !ok { - return fmt.Errorf("not Found: %s", n) - } - - spaceID := rs.Primary.Attributes["space_id"] - if spaceID == "" { - return fmt.Errorf("no space_id is set") - } - - client := testAccProvider.Meta().(*contentful.Client) - - contentfulAsset, err := client.Resources.Get(spaceID, rs.Primary.ID) - if err != nil { - return err - } - - *upload = *contentfulAsset - - return nil - } -} - -func testAccCheckContentfulUploadAttributes(upload *contentful.Resource, attrs map[string]interface{}) resource.TestCheckFunc { - return func(s *terraform.State) error { - - spaceIDCheck := attrs["space_id"].(string) - if upload.Sys.Space.Sys.ID != spaceIDCheck { - return fmt.Errorf("space id does not match: %s, %s", upload.Sys.Space.Sys.ID, spaceIDCheck) - } - - return nil - } -} - -func testAccContentfulUploadDestroy(s *terraform.State) error { - for _, rs := range s.RootModule().Resources { - if rs.Type != "contentful_entry" { - continue - } - - // get space id from resource data - spaceID := rs.Primary.Attributes["space_id"] - if spaceID == "" { - return fmt.Errorf("no space_id is set") - } - - // check webhook resource id - if rs.Primary.ID == "" { - return fmt.Errorf("no asset ID is set") - } - - // sdk client - client := testAccProvider.Meta().(*contentful.Client) - - asset, _ := client.Assets.Get(spaceID, rs.Primary.ID) - if asset == nil { - return nil - } - - return fmt.Errorf("asset still exists with id: %s", rs.Primary.ID) - } - - return nil -} - -var testAccContentfulUploadConfig = ` -resource "contentful_upload" "myupload" { - space_id = "` + spaceID + `" - file_path = "/home/kantoor/go/src/github.com/labd/terraform-contentful/local/upload_test.png" - asset_id = "upload_test" - locale = "en-US" - title = "This is an asset" - description = "Uploaded asset!" -} -` From 7fd15ef68573fc05afb8535052e217d7ce65cd5a Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Fri, 3 Jul 2020 09:19:25 +0200 Subject: [PATCH 076/192] Uploads resource to different branch. --- contentful/contentful_go_.txt | 63 ++++++++ contentful/resource_contentful_upload.go | 148 ++++++++++++++++++ contentful/resource_contentful_upload_test.go | 110 +++++++++++++ 3 files changed, 321 insertions(+) create mode 100644 contentful/contentful_go_.txt create mode 100644 contentful/resource_contentful_upload.go create mode 100644 contentful/resource_contentful_upload_test.go diff --git a/contentful/contentful_go_.txt b/contentful/contentful_go_.txt new file mode 100644 index 0000000..5cd95f7 --- /dev/null +++ b/contentful/contentful_go_.txt @@ -0,0 +1,63 @@ +To make uploads resource work, the do function in the contentful go sdk +needs to be edited. This method will return an error containing the +response body. This is not included in the official repo, because this +is a temporary (and an ugly) fix. + +func (c *Client) do(req *http.Request, v interface{}) error { + if c.Debug == true { + command, _ := http2curl.GetCurlCommand(req) + fmt.Println(command) + } + + res, err := c.client.Do(req) + if err != nil { + return err + } + + if res.StatusCode >= 200 && res.StatusCode < 400 { + // Upload/Create Resource response cannot be decoded + if c.api == "URC" && req.Method == "POST" { + // Nulpointer workaround, set response as error and catch in service + buf := new(bytes.Buffer) + buf.ReadFrom(res.Body) + err = errors.New(buf.String()) + defer res.Body.Close() + return err + } else { + if v != nil { + defer res.Body.Close() + err = json.NewDecoder(res.Body).Decode(v) + if err != nil { + return err + } + } + } + + return nil + } + + // parse api response + apiError := c.handleError(req, res) + + // return apiError if it is not rate limit error + if _, ok := apiError.(RateLimitExceededError); !ok { + return apiError + } + + resetHeader := res.Header.Get("x-contentful-ratelimit-reset") + + // return apiError if Ratelimit-Reset header is not presented + if resetHeader == "" { + return apiError + } + + // wait X-Contentful-Ratelimit-Reset amount of seconds + waitSeconds, err := strconv.Atoi(resetHeader) + if err != nil { + return apiError + } + + time.Sleep(time.Second * time.Duration(waitSeconds)) + + return c.do(req, v) +} \ No newline at end of file diff --git a/contentful/resource_contentful_upload.go b/contentful/resource_contentful_upload.go new file mode 100644 index 0000000..fceb740 --- /dev/null +++ b/contentful/resource_contentful_upload.go @@ -0,0 +1,148 @@ +package contentful + +import ( + "encoding/json" + "fmt" + "github.com/hashicorp/terraform/helper/schema" + contentful "github.com/labd/contentful-go" +) + +func resourceContentfulUpload() *schema.Resource { + return &schema.Resource{ + Create: resourceCreateUpload, + Read: resourceReadUpload, + Update: nil, + Delete: resourceDeleteUpload, + + Schema: map[string]*schema.Schema{ + "space_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "file_path": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "asset_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "locale": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "title": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "description": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + }, + } +} + +func resourceCreateUpload(d *schema.ResourceData, m interface{}) (err error) { + uploadClient := contentful.NewResourceClient(CMAToken) + uploadClient.SetOrganization(orgID) + client := m.(*contentful.Client) + + upload := contentful.Resource{} + + fmt.Println(d.Get("space_id").(string)) + fmt.Println(d.Get("file_path").(string)) + + response := uploadClient.Resources.Create(d.Get("space_id").(string), d.Get("file_path").(string)) + err = json.Unmarshal([]byte(response.Error()), &upload) + + d.SetId(upload.Sys.ID) + + if err := setUploadProperties(d, &upload); err != nil { + return err + } + + asset := &contentful.Asset{ + Sys: &contentful.Sys{ + ID: d.Get("asset_id").(string), + Version: 0, + }, + Locale: d.Get("locale").(string), + Fields: &contentful.AssetFields{ + Title: map[string]string{ + d.Get("locale").(string): d.Get("title").(string), + }, + Description: map[string]string{ + d.Get("locale").(string): d.Get("description").(string), + }, + File: map[string]*contentful.File{ + d.Get("locale").(string): { + UploadFrom: &contentful.UploadFrom{ + Sys: &contentful.Sys{ + ID: "upload.Sys.ID", + LinkType: "Upload", + }, + }, + }, + }, + }, + } + + err = client.Assets.Upsert(d.Get("space_id").(string), asset) + if err != nil { + return err + } + + err = client.Assets.Process(d.Get("space_id").(string), asset) + if err != nil { + return err + } + + err = client.Assets.Publish(spaceID, asset) + if err != nil { + return err + } + + return err +} + +func resourceReadUpload(d *schema.ResourceData, m interface{}) (err error) { + client := m.(*contentful.Client) + spaceID := d.Get("space_id").(string) + uploadID := d.Id() + + upload, err := client.Resources.Get(spaceID, uploadID) + if _, ok := err.(contentful.NotFoundError); ok { + d.SetId("") + return err + } + + return setUploadProperties(d, upload) +} + +func resourceDeleteUpload(d *schema.ResourceData, m interface{}) (err error) { + client := m.(*contentful.Client) + spaceID := d.Get("space_id").(string) + uploadID := d.Id() + + _, err = client.Resources.Get(spaceID, uploadID) + if err != nil { + return err + } + + return client.Resources.Delete(spaceID, uploadID) +} + +func setUploadProperties(d *schema.ResourceData, resource *contentful.Resource) (err error) { + if err = d.Set("space_id", resource.Sys.Space.Sys.ID); err != nil { + return err + } + + return err +} diff --git a/contentful/resource_contentful_upload_test.go b/contentful/resource_contentful_upload_test.go new file mode 100644 index 0000000..047e71a --- /dev/null +++ b/contentful/resource_contentful_upload_test.go @@ -0,0 +1,110 @@ +package contentful + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + contentful "github.com/labd/contentful-go" +) + +func TestAccContentfulUpload_Basic(t *testing.T) { + var upload contentful.Resource + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccContentfulUploadDestroy, + Steps: []resource.TestStep{ + { + Config: testAccContentfulUploadConfig, + Check: resource.ComposeTestCheckFunc( + testAccCheckContentfulUploadExists("contentful_asset.myupload", &upload), + testAccCheckContentfulUploadAttributes(&upload, map[string]interface{}{ + "space_id": spaceID, + }), + ), + }, + }, + }) +} + +func testAccCheckContentfulUploadExists(n string, upload *contentful.Resource) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("not Found: %s", n) + } + + spaceID := rs.Primary.Attributes["space_id"] + if spaceID == "" { + return fmt.Errorf("no space_id is set") + } + + client := testAccProvider.Meta().(*contentful.Client) + + contentfulAsset, err := client.Resources.Get(spaceID, rs.Primary.ID) + if err != nil { + return err + } + + *upload = *contentfulAsset + + return nil + } +} + +func testAccCheckContentfulUploadAttributes(upload *contentful.Resource, attrs map[string]interface{}) resource.TestCheckFunc { + return func(s *terraform.State) error { + + spaceIDCheck := attrs["space_id"].(string) + if upload.Sys.Space.Sys.ID != spaceIDCheck { + return fmt.Errorf("space id does not match: %s, %s", upload.Sys.Space.Sys.ID, spaceIDCheck) + } + + return nil + } +} + +func testAccContentfulUploadDestroy(s *terraform.State) error { + for _, rs := range s.RootModule().Resources { + if rs.Type != "contentful_entry" { + continue + } + + // get space id from resource data + spaceID := rs.Primary.Attributes["space_id"] + if spaceID == "" { + return fmt.Errorf("no space_id is set") + } + + // check webhook resource id + if rs.Primary.ID == "" { + return fmt.Errorf("no asset ID is set") + } + + // sdk client + client := testAccProvider.Meta().(*contentful.Client) + + asset, _ := client.Assets.Get(spaceID, rs.Primary.ID) + if asset == nil { + return nil + } + + return fmt.Errorf("asset still exists with id: %s", rs.Primary.ID) + } + + return nil +} + +var testAccContentfulUploadConfig = ` +resource "contentful_upload" "myupload" { + space_id = "` + spaceID + `" + file_path = "/home/kantoor/go/src/github.com/labd/terraform-contentful/local/upload_test.png" + asset_id = "upload_test" + locale = "en-US" + title = "This is an asset" + description = "Uploaded asset!" +} +` From 504539fd5801eb48bf18f8cbac5ee946389cd06a Mon Sep 17 00:00:00 2001 From: Tim Leguijt Date: Thu, 22 Oct 2020 11:21:53 +0200 Subject: [PATCH 077/192] Update README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a8b9bdf..5641631 100644 --- a/README.md +++ b/README.md @@ -150,7 +150,7 @@ Julien Fabre: [Writing a Terraform provider](http://blog.jfabre.net/2017/01/22/w ## Support -If you have a problem with this provider, please file an [issue](https://github.com/contentful-labs/terraform-contentful/issues/new) here on Github. +If you have a problem with this provider, please file an [issue](https://github.com/labd/terraform-provider-contentful/issues/new) here on Github. ## License From 9932c1c830fd8d09e068a5db31fe9719dfe4ba9c Mon Sep 17 00:00:00 2001 From: Tim Leguijt Date: Thu, 22 Oct 2020 11:24:15 +0200 Subject: [PATCH 078/192] Change build make target --- Dockerfile-test | 11 ----------- Makefile | 4 ++-- install-dependencies.sh | 6 ------ 3 files changed, 2 insertions(+), 19 deletions(-) delete mode 100644 Dockerfile-test delete mode 100755 install-dependencies.sh diff --git a/Dockerfile-test b/Dockerfile-test deleted file mode 100644 index c03abc1..0000000 --- a/Dockerfile-test +++ /dev/null @@ -1,11 +0,0 @@ -FROM golang:1.14.2 - -WORKDIR /go/src/github.com/labd/terraform-contentful - -# http://stackoverflow.com/questions/39278756/cache-go-get-in-docker-build -COPY ./install-dependencies.sh /go/src/github.com/labd/terraform-contentful -RUN ./install-dependencies.sh - -COPY . /go/src/github.com/labd/terraform-contentful - -CMD go test -v \ No newline at end of file diff --git a/Makefile b/Makefile index 3b44a7a..ff80022 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ .PHONY: build build: - sudo -S docker build -t terraform-provider-contentful -f Dockerfile-test . + go build .PHONY: test-unit test-unit: build @@ -15,7 +15,7 @@ test-unit: build .PHONY: interactive interactive: sudo -S docker run -it \ - -v $(shell pwd):/go/src/github.com/labd/terraform-contentful \ + -v $(shell pwd):/go/src/github.com/labd/terraform-provider-contentful \ -e CONTENTFUL_MANAGEMENT_TOKEN=${CONTENTFUL_MANAGEMENT_TOKEN} \ -e CONTENTFUL_ORGANIZATION_ID=${CONTENTFUL_ORGANIZATION_ID} \ -e SPACE_ID=${SPACE_ID} \ diff --git a/install-dependencies.sh b/install-dependencies.sh deleted file mode 100755 index e2c4911..0000000 --- a/install-dependencies.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env bash - -go get github.com/hashicorp/terraform/terraform -go get github.com/hashicorp/terraform/helper/resource -go get github.com/hashicorp/terraform/helper/schema -go get github.com/labd/contentful-go From 38f623a0fae953b3bc3c7facaff6457dd28ef5a2 Mon Sep 17 00:00:00 2001 From: Tim Leguijt Date: Thu, 22 Oct 2020 11:24:48 +0200 Subject: [PATCH 079/192] Rename to terraform-provider-contentful --- README.md | 6 +- contentful/resource_contentful_upload_test.go | 2 +- go.mod | 4 +- go.sum | 439 ++++++++++++++++++ main.go | 2 +- 5 files changed, 446 insertions(+), 7 deletions(-) create mode 100644 go.sum diff --git a/README.md b/README.md index 5641631..cbeb1ed 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -![Go](https://github.com/labd/terraform-contentful/workflows/Go/badge.svg?branch=master) -[![codecov](https://codecov.io/gh/labd/terraform-contentful/branch/master/graph/badge.svg)](https://codecov.io/gh/labd/terraform-contentful) -[![license](https://img.shields.io/github/license/labd/terraform-contentful.svg)](https://github.com/labd/terraform-contentful/blob/master/LICENSE) +![Go](https://github.com/labd/terraform-provider-contentful/workflows/Go/badge.svg?branch=master) +[![codecov](https://codecov.io/gh/labd/terraform-provider-contentful/branch/master/graph/badge.svg)](https://codecov.io/gh/labd/terraform-provider-contentful) +[![license](https://img.shields.io/github/license/labd/terraform-provider-contentful.svg)](https://github.com/labd/terraform-provider-contentful/blob/master/LICENSE) Terraform Provider for [Contentful's](https://www.contentful.com) Content Management API diff --git a/contentful/resource_contentful_upload_test.go b/contentful/resource_contentful_upload_test.go index 047e71a..100feb4 100644 --- a/contentful/resource_contentful_upload_test.go +++ b/contentful/resource_contentful_upload_test.go @@ -101,7 +101,7 @@ func testAccContentfulUploadDestroy(s *terraform.State) error { var testAccContentfulUploadConfig = ` resource "contentful_upload" "myupload" { space_id = "` + spaceID + `" - file_path = "/home/kantoor/go/src/github.com/labd/terraform-contentful/local/upload_test.png" + file_path = "/home/kantoor/go/src/github.com/labd/terraform-provider-contentful/local/upload_test.png" asset_id = "upload_test" locale = "en-US" title = "This is an asset" diff --git a/go.mod b/go.mod index a01d7c9..5f5915c 100644 --- a/go.mod +++ b/go.mod @@ -1,8 +1,8 @@ -module github.com/labd/terraform-contentful +module github.com/labd/terraform-provider-contentful go 1.14 require ( github.com/hashicorp/terraform v0.12.24 - github.com/labd/contentful-go v0.4.1-0.20200512094354-cc45b8138ed9 + github.com/labd/contentful-go v0.4.1-0.20201022091751-47d2076a5ad8 ) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..e31fc30 --- /dev/null +++ b/go.sum @@ -0,0 +1,439 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +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/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/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/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc= +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/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/go.mod h1:MgwOyqaIuKdG4TL/2ywSsIWKAfJfgHDo8ObuUk3t5sA= +github.com/Azure/go-autorest/autorest/validation v0.2.0/go.mod h1:3EEqHnBxQGHXRYq3HT1WyXAvT7LLY3tl70hw6tQIbjI= +github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= +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/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU= +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/go.mod h1:nuWgzSkT5PnyOd+272uUmV0dnAnAn42Mk7PiQC5VzN4= +github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409/go.mod h1:1pk82RBxDY/JZnPQrtqHlUFfCctgdorsd9M06fMynOM= +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/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/go.mod h1:T9M45xf79ahXVelWoOBmH0y4aC1t5kXO5BxwyakgIGA= +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/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= +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/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= +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/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/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas= +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 h1:2bNwBOmhyFEFcoB3tGvTD5xanq+4kyOZlB8wFYbMjkk= +github.com/bmatcuk/doublestar v1.1.5/go.mod h1:wiQtGV+rzVYxB7WIlirSN++5HPtPlXEo9MEoZQC/PmE= +github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= +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/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/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/coreos/bbolt v1.3.0/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +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/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +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/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/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +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/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= +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/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/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +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/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +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/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +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= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +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/gophercloud/gophercloud v0.0.0-20190208042652-bc37892e1968/go.mod h1:3WdhXV3rUYy9p6AUW8d94kr+HS62Y4VL9mBnFxsD8q4= +github.com/gophercloud/utils v0.0.0-20190128072930-fbb6ab446f01/go.mod h1:wjDF8z83zTeg5eMLml5EBSlAhbF7G8DobyI1YsMuyzw= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +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/hashicorp/aws-sdk-go-base v0.4.0/go.mod h1:eRhlz3c4nhqxFZJAahJEFL7gh6Jyj5rQmQc7F9eHFyQ= +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/go.mod h1:YuAtHxm2v74s+IjQwUG88dHBJPd5jL+cXr5BGVzSKhE= +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= +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 h1:Yv9YzBlAETjy6AOX9eLBZ3nshNVRREgerT/3nvxlGho= +github.com/hashicorp/go-hclog v0.0.0-20181001195459-61d530d6c27f/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= +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 h1:hRho44SAoNu1CBtn5r8Q9J3rCs4ZverWZ4R+UeeNuWM= +github.com/hashicorp/go-plugin v1.0.1-0.20190610192547-a1bc61569a26/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/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/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/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= +github.com/hashicorp/go-version v1.2.0 h1:3vNe/fWF5CBgRIguda1meWhsZHy3m8gCJ5wx+dIzX/E= +github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/hcl v0.0.0-20170504190234-a4b07c25de5f h1:UdxlrJz4JOnY8W+DbLISwf2B8WXEolNRA8BGCwI9jws= +github.com/hashicorp/hcl v0.0.0-20170504190234-a4b07c25de5f/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w= +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/memberlist v0.1.0/go.mod h1:ncdBp14cuox2iFOq3kDiquKU6fqsTBc3W6JvZwjxxsE= +github.com/hashicorp/serf v0.0.0-20160124182025-e4ec8cc423bb/go.mod h1:h/Ru6tmZazX7WO/GDmwdpS975F019L4t5ng5IgwbNrE= +github.com/hashicorp/terraform v0.12.24 h1:lTTswsCcmTOhTwuUl2NdjtJBCNdGqZmRGQi0cjFHYOM= +github.com/hashicorp/terraform v0.12.24/go.mod h1:eJcloDEx5ywM4a1tetIuVrlqklM0bUVRYJBYAh4CYzA= +github.com/hashicorp/terraform-config-inspect v0.0.0-20191212124732-c6ae6269b9d7/go.mod h1:p+ivJws3dpqbp1iP84+npOyAmTTOLMgCzrXd3GSdn/A= +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 h1:b5rjCoWHc7eqmAS4/qyk21ZsHyb6Mxv/jykxvNTkU4M= +github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= +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/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/joyent/triton-go v0.0.0-20180313100802-d8f9c0314926/go.mod h1:U+RSyWxWd04xTqnuOQxnai7XGS2PrPY2cfGoDKtMHjA= +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/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +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/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/labd/contentful-go v0.4.1-0.20201022091751-47d2076a5ad8 h1:gtVR7knJ1J9OFoLH4wfzCr8cvn27b1V3JVrXgCwE59c= +github.com/labd/contentful-go v0.4.1-0.20201022091751-47d2076a5ad8/go.mod h1:nU9FmlPmgIOwTWg2czqlpRMhPQplTaPuPjuz0oIcftM= +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/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/lusis/go-artifactory v0.0.0-20160115162124-7e4ce345df82/go.mod h1:y54tfGmO3NKssKveTEFFzH8C/akrSOy/iW9qEAUDV84= +github.com/masterzen/simplexml v0.0.0-20160608183007-4572e39b1ab9/go.mod h1:kCEbxUJlNDEBNbdQMkPSp6yaKcRXVI6f4ddk8Riv4bc= +github.com/masterzen/winrm v0.0.0-20190223112901-5e5c9a7fe54b/go.mod h1:wr1VqkwW0AB5JS0QLy5GpVMS9E3VtRoSYXUYyVk46KY= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-shellwords v1.0.4/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= +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/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw= +github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ= +github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= +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/go.mod h1:OaY7UOoTkkrX3wRwjpYRKafIkkyeD0UtweSHAWWiqQM= +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= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +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/go.mod h1:pKvZHwWrZowLUzftuFq7coarnxbBXU4aQh3N0BJOeeA= +github.com/mitchellh/prefixedio v0.0.0-20190213213902-5733675afd51/go.mod h1:kB1naBgV9ORnkiTVeyJOI1DavaJkG4oNIq0Af6ZVKUo= +github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY= +github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +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/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/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/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/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_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/common v0.2.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/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +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/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +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/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/spf13/afero v1.2.1 h1:qgMbHoJbPbw579P+1zVY+6n4nIFuIchaIjzZ/I/Yq8M= +github.com/spf13/afero v1.2.1/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.1.4/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/svanharmelen/jsonapi v0.0.0-20180618144545-0c0828c3f16d/go.mod h1:BSTlc8jOjh0niykqEGVXOLXdi9o0r0kR8tCYiMvjFgw= +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/go.mod h1:wk2XFUg6egk4tSDNZtXeKfe2G6690UVyt163PuUxBZk= +github.com/terraform-providers/terraform-provider-openstack v1.15.0/go.mod h1:2aQ6n/BtChAl1y2S60vebhyJyZXBsuAI5G4+lHrT1Ew= +github.com/tmc/grpc-websocket-proxy v0.0.0-20171017195756-830351dc03c6/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/ugorji/go v0.0.0-20180813092308-00b869d2f4a5/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ= +github.com/ulikunitz/xz v0.5.5 h1:pFrO0lVpTBXLpYw+pnLj6TbvHuyjXMfjGeCwSqCVwok= +github.com/ulikunitz/xz v0.5.5/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8= +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/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= +github.com/xiang90/probing v0.0.0-20160813154853-07dd2e8dfe18/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xlab/treeprint v0.0.0-20161029104018-1d6e34225557/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/zclconf/go-cty v1.0.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s= +github.com/zclconf/go-cty v1.1.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s= +github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8= +github.com/zclconf/go-cty v1.2.1 h1:vGMsygfmeCl4Xb6OA5U5XVAaQZ69FvoG7X2jUtQujb8= +github.com/zclconf/go-cty v1.2.1/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8= +github.com/zclconf/go-cty-yaml v1.0.1 h1:up11wlgAaDvlAGENcFDnZgkn0qUJurso7k6EpURKNF8= +github.com/zclconf/go-cty-yaml v1.0.1/go.mod h1:IP3Ylp0wQpYm50IHK8OZWKMu6sPJIUgKa8XhiVHura0= +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/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/zap v1.9.1/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-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-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/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/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= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +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= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +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/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= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/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= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190804053845-51ab0e2deafa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +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/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200507205054-480da3ebd79c/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0 h1:jbyannxz0XFD3zdjgrSUsaJbgpH4eTrkdhRChkHPfO8= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1 h1:j6XxA85m/6txkUCHvzlV5f+HBNl/1r5cZ2A/3IEFOO8= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/cheggaaa/pb.v1 v1.0.27/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= +gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +moul.io/http2curl v1.0.1-0.20190925090545-5cd742060b0e h1:C7q+e9M5nggAvWfVg9Nl66kebKeuJlP3FD58V4RR5wo= +moul.io/http2curl v1.0.1-0.20190925090545-5cd742060b0e/go.mod h1:nejbQVfXh96n9dSF6cH3Jsk/QI1Z2oEL7sSI2ifXFNA= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/main.go b/main.go index ff4faff..a2e9b51 100644 --- a/main.go +++ b/main.go @@ -3,7 +3,7 @@ package main import ( "github.com/hashicorp/terraform/plugin" "github.com/hashicorp/terraform/terraform" - "github.com/labd/terraform-contentful/contentful" + "github.com/labd/terraform-provider-contentful/contentful" ) func main() { From d07dc1d9dbc67f937452c424de10659589317c79 Mon Sep 17 00:00:00 2001 From: Tim Leguijt Date: Thu, 22 Oct 2020 22:53:55 +0200 Subject: [PATCH 080/192] Set contentful-go to v0.5.0 --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 5f5915c..13c4914 100644 --- a/go.mod +++ b/go.mod @@ -4,5 +4,5 @@ go 1.14 require ( github.com/hashicorp/terraform v0.12.24 - github.com/labd/contentful-go v0.4.1-0.20201022091751-47d2076a5ad8 + github.com/labd/contentful-go v0.5.0 ) diff --git a/go.sum b/go.sum index e31fc30..1c9388f 100644 --- a/go.sum +++ b/go.sum @@ -201,6 +201,8 @@ github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LE github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/labd/contentful-go v0.4.1-0.20201022091751-47d2076a5ad8 h1:gtVR7knJ1J9OFoLH4wfzCr8cvn27b1V3JVrXgCwE59c= github.com/labd/contentful-go v0.4.1-0.20201022091751-47d2076a5ad8/go.mod h1:nU9FmlPmgIOwTWg2czqlpRMhPQplTaPuPjuz0oIcftM= +github.com/labd/contentful-go v0.5.0 h1:nm7dHLDkNPZ6ZkxCoIy4Xo7/UcYsmJdOxS+SK8RIXhw= +github.com/labd/contentful-go v0.5.0/go.mod h1:nU9FmlPmgIOwTWg2czqlpRMhPQplTaPuPjuz0oIcftM= 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= From 078c3de9f1747730452b43ff11ab1fb49e4adb1e Mon Sep 17 00:00:00 2001 From: Tim Leguijt Date: Thu, 22 Oct 2020 22:54:05 +0200 Subject: [PATCH 081/192] Add release action --- .github/workflows/release.yml | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..3b65d7c --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,31 @@ +name: release +on: + push: + tags: + - 'v*' +jobs: + goreleaser: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Unshallow + run: git fetch --prune --unshallow + - name: Set up Go + uses: actions/setup-go@v2 + with: + go-version: 1.14 + - name: Import GPG key + id: import_gpg + uses: paultyng/ghaction-import-gpg@v2.1.0 + env: + GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} + PASSPHRASE: ${{ secrets.PASSPHRASE }} + - name: Run GoReleaser + uses: goreleaser/goreleaser-action@v2 + with: + version: latest + args: release --rm-dist + env: + GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From aa6015cabf5326d69223c819eb1e14ad05002211 Mon Sep 17 00:00:00 2001 From: Tim Leguijt Date: Thu, 22 Oct 2020 22:55:53 +0200 Subject: [PATCH 082/192] Prepare changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..5416738 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,3 @@ +0.1.0 (unreleased) +================== +Initial release \ No newline at end of file From 03253bea56e85cab2a77332bfb6c16271fb86a2d Mon Sep 17 00:00:00 2001 From: Tim Leguijt Date: Mon, 26 Oct 2020 09:47:55 +0100 Subject: [PATCH 083/192] Removed unfinished 'upload' resources Were placed in seperate branch --- contentful/resource_contentful_upload.go | 148 ------------------ contentful/resource_contentful_upload_test.go | 110 ------------- 2 files changed, 258 deletions(-) delete mode 100644 contentful/resource_contentful_upload.go delete mode 100644 contentful/resource_contentful_upload_test.go diff --git a/contentful/resource_contentful_upload.go b/contentful/resource_contentful_upload.go deleted file mode 100644 index fceb740..0000000 --- a/contentful/resource_contentful_upload.go +++ /dev/null @@ -1,148 +0,0 @@ -package contentful - -import ( - "encoding/json" - "fmt" - "github.com/hashicorp/terraform/helper/schema" - contentful "github.com/labd/contentful-go" -) - -func resourceContentfulUpload() *schema.Resource { - return &schema.Resource{ - Create: resourceCreateUpload, - Read: resourceReadUpload, - Update: nil, - Delete: resourceDeleteUpload, - - Schema: map[string]*schema.Schema{ - "space_id": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - }, - "file_path": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - }, - "asset_id": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - }, - "locale": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - }, - "title": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - }, - "description": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - }, - }, - } -} - -func resourceCreateUpload(d *schema.ResourceData, m interface{}) (err error) { - uploadClient := contentful.NewResourceClient(CMAToken) - uploadClient.SetOrganization(orgID) - client := m.(*contentful.Client) - - upload := contentful.Resource{} - - fmt.Println(d.Get("space_id").(string)) - fmt.Println(d.Get("file_path").(string)) - - response := uploadClient.Resources.Create(d.Get("space_id").(string), d.Get("file_path").(string)) - err = json.Unmarshal([]byte(response.Error()), &upload) - - d.SetId(upload.Sys.ID) - - if err := setUploadProperties(d, &upload); err != nil { - return err - } - - asset := &contentful.Asset{ - Sys: &contentful.Sys{ - ID: d.Get("asset_id").(string), - Version: 0, - }, - Locale: d.Get("locale").(string), - Fields: &contentful.AssetFields{ - Title: map[string]string{ - d.Get("locale").(string): d.Get("title").(string), - }, - Description: map[string]string{ - d.Get("locale").(string): d.Get("description").(string), - }, - File: map[string]*contentful.File{ - d.Get("locale").(string): { - UploadFrom: &contentful.UploadFrom{ - Sys: &contentful.Sys{ - ID: "upload.Sys.ID", - LinkType: "Upload", - }, - }, - }, - }, - }, - } - - err = client.Assets.Upsert(d.Get("space_id").(string), asset) - if err != nil { - return err - } - - err = client.Assets.Process(d.Get("space_id").(string), asset) - if err != nil { - return err - } - - err = client.Assets.Publish(spaceID, asset) - if err != nil { - return err - } - - return err -} - -func resourceReadUpload(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Client) - spaceID := d.Get("space_id").(string) - uploadID := d.Id() - - upload, err := client.Resources.Get(spaceID, uploadID) - if _, ok := err.(contentful.NotFoundError); ok { - d.SetId("") - return err - } - - return setUploadProperties(d, upload) -} - -func resourceDeleteUpload(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Client) - spaceID := d.Get("space_id").(string) - uploadID := d.Id() - - _, err = client.Resources.Get(spaceID, uploadID) - if err != nil { - return err - } - - return client.Resources.Delete(spaceID, uploadID) -} - -func setUploadProperties(d *schema.ResourceData, resource *contentful.Resource) (err error) { - if err = d.Set("space_id", resource.Sys.Space.Sys.ID); err != nil { - return err - } - - return err -} diff --git a/contentful/resource_contentful_upload_test.go b/contentful/resource_contentful_upload_test.go deleted file mode 100644 index 100feb4..0000000 --- a/contentful/resource_contentful_upload_test.go +++ /dev/null @@ -1,110 +0,0 @@ -package contentful - -import ( - "fmt" - "testing" - - "github.com/hashicorp/terraform/helper/resource" - "github.com/hashicorp/terraform/terraform" - contentful "github.com/labd/contentful-go" -) - -func TestAccContentfulUpload_Basic(t *testing.T) { - var upload contentful.Resource - - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccContentfulUploadDestroy, - Steps: []resource.TestStep{ - { - Config: testAccContentfulUploadConfig, - Check: resource.ComposeTestCheckFunc( - testAccCheckContentfulUploadExists("contentful_asset.myupload", &upload), - testAccCheckContentfulUploadAttributes(&upload, map[string]interface{}{ - "space_id": spaceID, - }), - ), - }, - }, - }) -} - -func testAccCheckContentfulUploadExists(n string, upload *contentful.Resource) resource.TestCheckFunc { - return func(s *terraform.State) error { - rs, ok := s.RootModule().Resources[n] - if !ok { - return fmt.Errorf("not Found: %s", n) - } - - spaceID := rs.Primary.Attributes["space_id"] - if spaceID == "" { - return fmt.Errorf("no space_id is set") - } - - client := testAccProvider.Meta().(*contentful.Client) - - contentfulAsset, err := client.Resources.Get(spaceID, rs.Primary.ID) - if err != nil { - return err - } - - *upload = *contentfulAsset - - return nil - } -} - -func testAccCheckContentfulUploadAttributes(upload *contentful.Resource, attrs map[string]interface{}) resource.TestCheckFunc { - return func(s *terraform.State) error { - - spaceIDCheck := attrs["space_id"].(string) - if upload.Sys.Space.Sys.ID != spaceIDCheck { - return fmt.Errorf("space id does not match: %s, %s", upload.Sys.Space.Sys.ID, spaceIDCheck) - } - - return nil - } -} - -func testAccContentfulUploadDestroy(s *terraform.State) error { - for _, rs := range s.RootModule().Resources { - if rs.Type != "contentful_entry" { - continue - } - - // get space id from resource data - spaceID := rs.Primary.Attributes["space_id"] - if spaceID == "" { - return fmt.Errorf("no space_id is set") - } - - // check webhook resource id - if rs.Primary.ID == "" { - return fmt.Errorf("no asset ID is set") - } - - // sdk client - client := testAccProvider.Meta().(*contentful.Client) - - asset, _ := client.Assets.Get(spaceID, rs.Primary.ID) - if asset == nil { - return nil - } - - return fmt.Errorf("asset still exists with id: %s", rs.Primary.ID) - } - - return nil -} - -var testAccContentfulUploadConfig = ` -resource "contentful_upload" "myupload" { - space_id = "` + spaceID + `" - file_path = "/home/kantoor/go/src/github.com/labd/terraform-provider-contentful/local/upload_test.png" - asset_id = "upload_test" - locale = "en-US" - title = "This is an asset" - description = "Uploaded asset!" -} -` From 98a28ed9262d2518b16afd32aa18f07b8e3d8933 Mon Sep 17 00:00:00 2001 From: Tim Leguijt Date: Mon, 26 Oct 2020 09:51:06 +0100 Subject: [PATCH 084/192] v0.1.0 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5416738..d2ca120 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,3 @@ -0.1.0 (unreleased) +0.1.0 (2020-10-26) ================== Initial release \ No newline at end of file From b41486e56c4d27ee7cc6c0e5ac7fd770c8143794 Mon Sep 17 00:00:00 2001 From: Tim Leguijt Date: Mon, 26 Oct 2020 10:40:53 +0100 Subject: [PATCH 085/192] Add goreleaser --- .goreleaser.yml | 55 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 .goreleaser.yml diff --git a/.goreleaser.yml b/.goreleaser.yml new file mode 100644 index 0000000..3166e83 --- /dev/null +++ b/.goreleaser.yml @@ -0,0 +1,55 @@ +project_name: terraform-provider-contenful + +builds: +- env: + # goreleaser does not work with CGO, it could also complicate + # usage by users in CI/CD systems like Terraform Cloud where + # they are unable to install libraries. + - CGO_ENABLED=0 + mod_timestamp: '{{ .CommitTimestamp }}' + flags: + - -trimpath + ldflags: + - '-s -w -X main.version={{.Version}} -X main.commit={{.Commit}}' + goos: + - freebsd + - windows + - linux + - darwin + goarch: + - amd64 + - '386' + - arm + - arm64 + ignore: + - goos: darwin + goarch: '386' + binary: '{{ .ProjectName }}_v{{ .Version }}' + +archives: +- format: zip + name_template: '{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}' + +checksum: + name_template: '{{ .ProjectName }}_{{ .Version }}_SHA256SUMS' + algorithm: sha256 + +changelog: + sort: asc + filters: + exclude: + - "^docs:" + - "^test:" + +signs: + - artifacts: checksum + args: + # if you are using this is a GitHub action or some other automated pipeline, you + # need to pass the batch flag to indicate its not interactive. + - "--batch" + - "--local-user" + - "{{ .Env.GPG_FINGERPRINT }}" # set this environment variable for your signing key + - "--output" + - "${signature}" + - "--detach-sign" + - "${artifact}" From 994bc8bb0bc6f35af7d0e393b2df28202048b73e Mon Sep 17 00:00:00 2001 From: Tim Leguijt Date: Mon, 26 Oct 2020 11:05:05 +0100 Subject: [PATCH 086/192] Fixed typo --- .goreleaser.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.goreleaser.yml b/.goreleaser.yml index 3166e83..fb1141f 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -1,4 +1,4 @@ -project_name: terraform-provider-contenful +project_name: terraform-provider-contentful builds: - env: From 393ced5e1061cb66e19132de3c58360b3ad4bc38 Mon Sep 17 00:00:00 2001 From: Tim Leguijt Date: Mon, 26 Oct 2020 12:21:13 +0100 Subject: [PATCH 087/192] try GPG_PASSPHRASE --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3b65d7c..e97c501 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -20,7 +20,7 @@ jobs: uses: paultyng/ghaction-import-gpg@v2.1.0 env: GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} - PASSPHRASE: ${{ secrets.PASSPHRASE }} + PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} - name: Run GoReleaser uses: goreleaser/goreleaser-action@v2 with: From 174f8548855b1759f54eeef754cb04067ea0aa9f Mon Sep 17 00:00:00 2001 From: Querijn de Graaf Date: Thu, 29 Apr 2021 22:17:23 +0200 Subject: [PATCH 088/192] Add `testacc` option to makefile to run without docker, update changelog --- CHANGELOG.md | 15 +++++++++++++++ Makefile | 8 +++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d2ca120..21e6f99 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,18 @@ +0.3.0 (2021-04-29) +================== +Re-release of 0.1.0 to fix registry. +# Features + +Create, update and delete Contentful resources: +- [x] Spaces +- [x] Content Types +- [x] API Keys +- [x] Webhooks +- [x] Locales +- [x] Environments +- [x] Entries +- [x] Assets + 0.1.0 (2020-10-26) ================== Initial release \ No newline at end of file diff --git a/Makefile b/Makefile index ff80022..46a67b4 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,8 @@ -.PHONY: build +.PHONY: build, test-unit, interactive, testacc + build: go build -.PHONY: test-unit test-unit: build sudo docker run \ -e CONTENTFUL_MANAGEMENT_TOKEN=${CONTENTFUL_MANAGEMENT_TOKEN} \ @@ -12,7 +12,6 @@ test-unit: build terraform-provider-contentful \ go test ./... -v -.PHONY: interactive interactive: sudo -S docker run -it \ -v $(shell pwd):/go/src/github.com/labd/terraform-provider-contentful \ @@ -21,3 +20,6 @@ interactive: -e SPACE_ID=${SPACE_ID} \ terraform-provider-contentful \ bash + +testacc: + TF_ACC=1 go test -v ./... From 58f884c6c9b9ef38677539f0d64dd5a54cd62803 Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Fri, 30 Apr 2021 15:31:03 +0200 Subject: [PATCH 089/192] Fix validations issue (#8) * fix: validations bug fix Validations were not saved to the content models. I reverted the validations into the original schema, which makes the validations work for now. Keep in mind: this should be fixed in the future! --- contentful/resource_contentful_contenttype.go | 401 +----------------- .../resource_contentful_contenttype_test.go | 13 +- 2 files changed, 11 insertions(+), 403 deletions(-) diff --git a/contentful/resource_contentful_contenttype.go b/contentful/resource_contentful_contenttype.go index 59ebf4b..e160dcb 100644 --- a/contentful/resource_contentful_contenttype.go +++ b/contentful/resource_contentful_contenttype.go @@ -3,7 +3,6 @@ package contentful import ( "github.com/hashicorp/terraform/helper/schema" contentful "github.com/labd/contentful-go" - "time" ) func resourceContentfulContentType() *schema.Resource { @@ -70,10 +69,10 @@ func resourceContentfulContentType() *schema.Resource { Type: schema.TypeString, Required: true, }, - "validation": { + "validations": { Type: schema.TypeList, Optional: true, - Elem: generateValidationSchema(), + Elem: &schema.Schema{Type: schema.TypeString}, }, }, }, @@ -98,10 +97,10 @@ func resourceContentfulContentType() *schema.Resource { Optional: true, Default: false, }, - "validation": { + "validations": { Type: schema.TypeList, Optional: true, - Elem: generateValidationSchema(), + Elem: &schema.Schema{Type: schema.TypeString}, }, }, }, @@ -356,395 +355,3 @@ func processItems(fieldItems []interface{}) *contentful.FieldTypeArrayItem { } return items } - -// Expanders -// noinspection GoUnusedFunction -func expandContentTypeField(in interface{}) *contentful.Field { - field := &contentful.Field{} - m := in.(map[string]interface{}) - if v, ok := m["id"].(string); ok { - field.ID = v - } - if v, ok := m["name"].(string); ok { - field.Name = v - } - if v, ok := m["type"].(string); ok { - field.Type = v - } - if v, ok := m["link_type"].(string); ok { - field.LinkType = v - } - if v, ok := m["required"].(bool); ok { - field.Required = v - } - if v, ok := m["localized"].(bool); ok { - field.Localized = v - } - if v, ok := m["disabled"].(bool); ok { - field.Disabled = v - } - if v, ok := m["omitted"].(bool); ok { - field.Omitted = v - } - if v, ok := m["validation"].([]interface{}); ok && len(v) > 0 { - validations := make([]contentful.FieldValidation, len(v)) - for i, val := range v { - validations[i] = expandContentTypeFieldValidation(val) - } - field.Validations = validations - } - return field -} - -func expandContentTypeFieldValidation(in interface{}) contentful.FieldValidation { - m := in.(map[string]interface{}) - if v, ok := m["link"].([]string); ok { - return contentful.FieldValidationLink{ - LinkContentType: v, - } - } - if v, ok := m["mime_type"].([]string); ok { - return contentful.FieldValidationMimeType{ - MimeTypes: v, - } - } - if v, ok := m["dimension"].([]interface{}); ok { - return expandContentTypeFieldValidationDimension(v) - } - if v, ok := m["size"].([]interface{}); ok { - return expandContentTypeFieldValidationSize(v) - } - if v, ok := m["file_size"].([]interface{}); ok { - return expandContentTypeFieldValidationFileSize(v) - } - if v, ok := m["unique"].(bool); ok { - return contentful.FieldValidationUnique{ - Unique: v, - } - } - if v, ok := m["range"].([]interface{}); ok { - return expandContentTypeFieldValidationRange(v) - } - if v, ok := m["date"].([]interface{}); ok { - return expandContentTypeFieldValidationDate(v) - } - return nil -} - -func expandContentTypeFieldValidationDimension(in []interface{}) contentful.FieldValidation { - if len(in) == 0 || in[0] == nil { - return contentful.FieldValidationDimension{} - } - - validation := contentful.FieldValidationDimension{} - m := in[0].(map[string]interface{}) - if v, ok := m["min_width"].(float64); ok { - if validation.Width == nil { - validation.Width = &contentful.MinMax{} - } - validation.Width.Min = v - } - if v, ok := m["max_width"].(float64); ok { - if validation.Width == nil { - validation.Width = &contentful.MinMax{} - } - validation.Width.Max = v - } - if v, ok := m["min_height"].(float64); ok { - if validation.Height == nil { - validation.Width = &contentful.MinMax{} - } - validation.Height.Min = v - } - if v, ok := m["max_height"].(float64); ok { - if validation.Height == nil { - validation.Width = &contentful.MinMax{} - } - validation.Height.Max = v - } - if v, ok := m["err_message"].(string); ok { - validation.ErrorMessage = v - } - return validation -} - -func expandContentTypeFieldValidationSize(in []interface{}) contentful.FieldValidation { - if len(in) == 0 || in[0] == nil { - return contentful.FieldValidationSize{} - } - - validation := contentful.FieldValidationSize{} - m := in[0].(map[string]interface{}) - if v, ok := m["min"].(float64); ok { - if validation.Size == nil { - validation.Size = &contentful.MinMax{} - } - validation.Size.Min = v - } - if v, ok := m["max"].(float64); ok { - if validation.Size == nil { - validation.Size = &contentful.MinMax{} - } - validation.Size.Max = v - } - if v, ok := m["err_message"].(string); ok { - validation.ErrorMessage = v - } - return validation -} - -func expandContentTypeFieldValidationFileSize(in []interface{}) contentful.FieldValidation { - if len(in) == 0 || in[0] == nil { - return contentful.FieldValidationFileSize{} - } - - validation := contentful.FieldValidationFileSize{} - m := in[0].(map[string]interface{}) - if v, ok := m["min"].(float64); ok { - if validation.Size == nil { - validation.Size = &contentful.MinMax{} - } - validation.Size.Min = v - } - if v, ok := m["max"].(float64); ok { - if validation.Size == nil { - validation.Size = &contentful.MinMax{} - } - validation.Size.Max = v - } - if v, ok := m["err_message"].(string); ok { - validation.ErrorMessage = v - } - return validation -} - -func expandContentTypeFieldValidationRange(in []interface{}) contentful.FieldValidation { - if len(in) == 0 || in[0] == nil { - return contentful.FieldValidationRange{} - } - - validation := contentful.FieldValidationRange{} - m := in[0].(map[string]interface{}) - if v, ok := m["min"].(float64); ok { - if validation.Range == nil { - validation.Range = &contentful.MinMax{} - } - validation.Range.Min = v - } - if v, ok := m["max"].(float64); ok { - if validation.Range == nil { - validation.Range = &contentful.MinMax{} - } - validation.Range.Max = v - } - if v, ok := m["err_message"].(string); ok { - validation.ErrorMessage = v - } - return validation -} - -func expandContentTypeFieldValidationDate(in []interface{}) contentful.FieldValidation { - if len(in) == 0 || in[0] == nil { - return contentful.FieldValidationDate{} - } - - validation := contentful.FieldValidationDate{} - m := in[0].(map[string]interface{}) - if v, ok := m["min"].(time.Time); ok { - if validation.Range == nil { - validation.Range = &contentful.DateMinMax{} - } - validation.Range.Min = v - } - if v, ok := m["max"].(time.Time); ok { - if validation.Range == nil { - validation.Range = &contentful.DateMinMax{} - } - validation.Range.Max = v - } - if v, ok := m["err_message"].(string); ok { - validation.ErrorMessage = v - } - return validation -} - -// noinspection GoUnusedFunction -func expandContentTypeFieldValidationRegex(in []interface{}) contentful.FieldValidation { - if len(in) == 0 || in[0] == nil { - return contentful.FieldValidationRegex{} - } - - validation := contentful.FieldValidationRegex{} - m := in[0].(map[string]interface{}) - if v, ok := m["pattern"].(string); ok { - if validation.Regex == nil { - validation.Regex = &contentful.Regex{} - } - validation.Regex.Pattern = v - } - if v, ok := m["flags"].(string); ok { - if validation.Regex == nil { - validation.Regex = &contentful.Regex{} - } - validation.Regex.Flags = v - } - if v, ok := m["err_message"].(string); ok { - validation.ErrorMessage = v - } - return validation -} - -func generateValidationSchema() *schema.Resource { - return &schema.Resource{ - Schema: map[string]*schema.Schema{ - "link": { - Type: schema.TypeSet, - Optional: true, - Elem: &schema.Schema{Type: schema.TypeString}, - }, - "mime_type": { - Type: schema.TypeSet, - Optional: true, - Elem: &schema.Schema{Type: schema.TypeString}, - }, - "dimension": { - Type: schema.TypeList, - Optional: true, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "min_width": { - Type: schema.TypeFloat, - Required: true, - }, - "max_width": { - Type: schema.TypeFloat, - Required: true, - }, - "min_height": { - Type: schema.TypeFloat, - Required: true, - }, - "max_height": { - Type: schema.TypeFloat, - Required: true, - }, - "err_message": { - Type: schema.TypeString, - Required: true, - }, - }, - }, - }, - "size": { - Type: schema.TypeList, - Optional: true, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "min": { - Type: schema.TypeFloat, - Optional: true, - }, - "max": { - Type: schema.TypeFloat, - Optional: true, - }, - "err_message": { - Type: schema.TypeString, - Optional: true, - }, - }, - }, - }, - "file_size": { - Type: schema.TypeList, - Optional: true, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "min": { - Type: schema.TypeFloat, - Optional: true, - }, - "max": { - Type: schema.TypeFloat, - Optional: true, - }, - "err_message": { - Type: schema.TypeString, - Optional: true, - }, - }, - }, - }, - "unique": { - Type: schema.TypeBool, - Optional: true, - }, - "range": { - Type: schema.TypeList, - Optional: true, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "min": { - Type: schema.TypeFloat, - Optional: true, - }, - "max": { - Type: schema.TypeFloat, - Optional: true, - }, - "err_message": { - Type: schema.TypeString, - Optional: true, - }, - }, - }, - }, - "date": { - Type: schema.TypeList, - Optional: true, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "min": { - Type: schema.TypeString, - Optional: true, - }, - "max": { - Type: schema.TypeString, - Optional: true, - }, - "err_message": { - Type: schema.TypeString, - Optional: true, - }, - }, - }, - }, - "regex": { - Type: schema.TypeList, - Optional: true, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "pattern": { - Type: schema.TypeString, - Optional: true, - }, - "flags": { - Type: schema.TypeString, - Optional: true, - }, - "err_message": { - Type: schema.TypeString, - Optional: true, - }, - }, - }, - }, - }, - } -} diff --git a/contentful/resource_contentful_contenttype_test.go b/contentful/resource_contentful_contenttype_test.go index 68d30cc..3cb80f7 100644 --- a/contentful/resource_contentful_contenttype_test.go +++ b/contentful/resource_contentful_contenttype_test.go @@ -188,12 +188,13 @@ resource "contentful_contenttype" "mylinked_contenttype" { name = "Entry Link Field" type = "Link" link_type = "Entry" - dynamic "validation" { - for_each = ["{\"linkContentType\": [\"${contentful_contenttype.mycontenttype.id}\"]}"] - content { - link = lookup(contentful_contenttype.mycontenttype, "link", null) - } - } + validations = [ + jsonencode({ + linkContentType = [ + contentful_contenttype.mycontenttype.id + ] + }) + ] required = false } } From 430d8e9d60c33a12190a382775917c0f2361c59f Mon Sep 17 00:00:00 2001 From: Querijn de Graaf Date: Fri, 30 Apr 2021 15:38:23 +0200 Subject: [PATCH 090/192] Update Changelog --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 21e6f99..a19058c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +0.3.1 (2021-04-30) +================== +# Fixes + +* Fixed a bug causing validations in fields to not be saved properly to the models + 0.3.0 (2021-04-29) ================== Re-release of 0.1.0 to fix registry. From 3a07bc6d3cd13d3c49f757ec0f4dcd059eb64e83 Mon Sep 17 00:00:00 2001 From: Querijn de Graaf Date: Thu, 3 Jun 2021 15:06:12 +0200 Subject: [PATCH 091/192] Add tfplugindocs generated docs with examples, update gitignore --- .gitignore | 1 - docs/index.md | 21 ++++ docs/resources/apikey.md | 42 ++++++++ docs/resources/asset.md | 87 ++++++++++++++++ docs/resources/contenttype.md | 98 +++++++++++++++++++ docs/resources/entry.md | 67 +++++++++++++ docs/resources/environment.md | 38 +++++++ docs/resources/locale.md | 49 ++++++++++ docs/resources/space.md | 37 +++++++ docs/resources/webhook.md | 55 +++++++++++ .../resources/contentful_apikey/resource.tf | 6 ++ .../resources/contentful_asset/resource.tf | 23 +++++ .../contentful_contenttype/resource.tf | 30 ++++++ .../resources/contentful_entry/resource.tf | 19 ++++ .../contentful_environment/resource.tf | 4 + .../resources/contentful_locale/resource.tf | 10 ++ .../resources/contentful_space/resource.tf | 3 + .../resources/contentful_webhook/resource.tf | 16 +++ 18 files changed, 605 insertions(+), 1 deletion(-) create mode 100644 docs/index.md create mode 100644 docs/resources/apikey.md create mode 100644 docs/resources/asset.md create mode 100644 docs/resources/contenttype.md create mode 100644 docs/resources/entry.md create mode 100644 docs/resources/environment.md create mode 100644 docs/resources/locale.md create mode 100644 docs/resources/space.md create mode 100644 docs/resources/webhook.md create mode 100644 examples/resources/contentful_apikey/resource.tf create mode 100644 examples/resources/contentful_asset/resource.tf create mode 100644 examples/resources/contentful_contenttype/resource.tf create mode 100644 examples/resources/contentful_entry/resource.tf create mode 100644 examples/resources/contentful_environment/resource.tf create mode 100644 examples/resources/contentful_locale/resource.tf create mode 100644 examples/resources/contentful_space/resource.tf create mode 100644 examples/resources/contentful_webhook/resource.tf diff --git a/.gitignore b/.gitignore index 15dc197..42d73fc 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,6 @@ terraform-provider-contentful /dist/* coverage.txt -*.tf .terraform/ terraform.* crash.log diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..bdabb85 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,21 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "contentful Provider" +subcategory: "" +description: |- + +--- + +# contentful Provider + + + + + + +## Schema + +### Required + +- **cma_token** (String) The Contentful Management API token +- **organization_id** (String) The organization ID diff --git a/docs/resources/apikey.md b/docs/resources/apikey.md new file mode 100644 index 0000000..a28ec1b --- /dev/null +++ b/docs/resources/apikey.md @@ -0,0 +1,42 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "contentful_apikey Resource - terraform-provider-contentful" +subcategory: "" +description: |- + +--- + +# contentful_apikey (Resource) + + + +## Example Usage + +```terraform +resource "contentful_apikey" "myapikey" { + space_id = "space-id" + + name = "api-key-name" + description = "a-great-key" +} +``` + + +## Schema + +### Required + +- **name** (String) +- **space_id** (String) + +### Optional + +- **description** (String) +- **id** (String) The ID of this resource. + +### Read-Only + +- **access_token** (String) +- **version** (Number) + + diff --git a/docs/resources/asset.md b/docs/resources/asset.md new file mode 100644 index 0000000..602b68a --- /dev/null +++ b/docs/resources/asset.md @@ -0,0 +1,87 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "contentful_asset Resource - terraform-provider-contentful" +subcategory: "" +description: |- + +--- + +# contentful_asset (Resource) + + + +## Example Usage + +```terraform +resource "contentful_asset" "example_asset" { + asset_id = "test_asset" + locale = "en-US" + space_id = "space-id" + + fields { + title { + locale = "en-US" + content = "asset title" + } + description { + locale = "en-US" + content = "asset description" + } + file = { + upload = "https://images.ctfassets.net/fo9twyrwpveg/2VQx7vz73aMEYi20MMgCk0/66e502115b1f1f973a944b4bd2cc536f/IC-1H_Modern_Stack_Website.svg" + fileName = "example.jpeg" + contentType = "image/jpeg" + } + } + published = false + archived = false +} +``` + + +## Schema + +### Required + +- **archived** (Boolean) +- **asset_id** (String) +- **fields** (Block List, Min: 1) (see [below for nested schema](#nestedblock--fields)) +- **locale** (String) +- **published** (Boolean) +- **space_id** (String) + +### Optional + +- **id** (String) The ID of this resource. + +### Read-Only + +- **version** (Number) + + +### Nested Schema for `fields` + +Required: + +- **description** (Block List, Min: 1) (see [below for nested schema](#nestedblock--fields--description)) +- **file** (Map of String) +- **title** (Block List, Min: 1) (see [below for nested schema](#nestedblock--fields--title)) + + +### Nested Schema for `fields.description` + +Required: + +- **content** (String) +- **locale** (String) + + + +### Nested Schema for `fields.title` + +Required: + +- **content** (String) +- **locale** (String) + + diff --git a/docs/resources/contenttype.md b/docs/resources/contenttype.md new file mode 100644 index 0000000..67ef6d8 --- /dev/null +++ b/docs/resources/contenttype.md @@ -0,0 +1,98 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "contentful_contenttype Resource - terraform-provider-contentful" +subcategory: "" +description: |- + +--- + +# contentful_contenttype (Resource) + + + +## Example Usage + +```terraform +resource "contentful_contenttype" "example_contenttype" { + space_id = "space-id" + name = "tf_linked" + description = "content type description" + display_field = "asset_field" + field { + id = "asset_field" + name = "Asset Field" + type = "Array" + items { + type = "Link" + link_type = "Asset" + } + required = true + } + field { + id = "entry_link_field" + name = "Entry Link Field" + type = "Link" + link_type = "Entry" + validations = [ + jsonencode({ + linkContentType = [ + contentful_contenttype.some_other_content_type.id + ] + }) + ] + required = false + } +} +``` + + +## Schema + +### Required + +- **display_field** (String) +- **field** (Block List, Min: 1) (see [below for nested schema](#nestedblock--field)) +- **name** (String) +- **space_id** (String) + +### Optional + +- **description** (String) +- **id** (String) The ID of this resource. + +### Read-Only + +- **version** (Number) + + +### Nested Schema for `field` + +Required: + +- **id** (String) The ID of this resource. +- **name** (String) +- **type** (String) + +Optional: + +- **disabled** (Boolean) +- **items** (Block List, Max: 1) (see [below for nested schema](#nestedblock--field--items)) +- **link_type** (String) +- **localized** (Boolean) +- **omitted** (Boolean) +- **required** (Boolean) +- **validations** (List of String) + + +### Nested Schema for `field.items` + +Required: + +- **link_type** (String) +- **type** (String) + +Optional: + +- **validations** (List of String) + + diff --git a/docs/resources/entry.md b/docs/resources/entry.md new file mode 100644 index 0000000..165a9ca --- /dev/null +++ b/docs/resources/entry.md @@ -0,0 +1,67 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "contentful_entry Resource - terraform-provider-contentful" +subcategory: "" +description: |- + +--- + +# contentful_entry (Resource) + + + +## Example Usage + +```terraform +resource "contentful_entry" "example_entry" { + entry_id = "mytestentry" + space_id = "space-id" + contenttype_id = "type-id" + locale = "en-US" + field { + id = "field1" + content = "Hello, World!" + locale = "en-US" + } + field { + id = "field2" + content = "Lettuce is healthy!" + locale = "en-US" + } + published = false + archived = false + depends_on = [contentful_contenttype.mycontenttype] +} +``` + + +## Schema + +### Required + +- **archived** (Boolean) +- **contenttype_id** (String) +- **entry_id** (String) +- **field** (Block List, Min: 1) (see [below for nested schema](#nestedblock--field)) +- **locale** (String) +- **published** (Boolean) +- **space_id** (String) + +### Optional + +- **id** (String) The ID of this resource. + +### Read-Only + +- **version** (Number) + + +### Nested Schema for `field` + +Required: + +- **content** (String) +- **id** (String) The ID of this resource. +- **locale** (String) + + diff --git a/docs/resources/environment.md b/docs/resources/environment.md new file mode 100644 index 0000000..c016889 --- /dev/null +++ b/docs/resources/environment.md @@ -0,0 +1,38 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "contentful_environment Resource - terraform-provider-contentful" +subcategory: "" +description: |- + +--- + +# contentful_environment (Resource) + + + +## Example Usage + +```terraform +resource "contentful_environment" "example_environment" { + space_id = "spaced-id" + name = "environment-name" +} +``` + + +## Schema + +### Required + +- **name** (String) +- **space_id** (String) + +### Optional + +- **id** (String) The ID of this resource. + +### Read-Only + +- **version** (Number) + + diff --git a/docs/resources/locale.md b/docs/resources/locale.md new file mode 100644 index 0000000..a199bd6 --- /dev/null +++ b/docs/resources/locale.md @@ -0,0 +1,49 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "contentful_locale Resource - terraform-provider-contentful" +subcategory: "" +description: |- + +--- + +# contentful_locale (Resource) + + + +## Example Usage + +```terraform +resource "contentful_locale" "example_locale" { + space_id = "spaced-id" + + name = "locale-name" + code = "de" + fallback_code = "en-US" + optional = false + cda = false + cma = true +} +``` + + +## Schema + +### Required + +- **code** (String) +- **name** (String) +- **space_id** (String) + +### Optional + +- **cda** (Boolean) +- **cma** (Boolean) +- **fallback_code** (String) +- **id** (String) The ID of this resource. +- **optional** (Boolean) + +### Read-Only + +- **version** (Number) + + diff --git a/docs/resources/space.md b/docs/resources/space.md new file mode 100644 index 0000000..23d9686 --- /dev/null +++ b/docs/resources/space.md @@ -0,0 +1,37 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "contentful_space Resource - terraform-provider-contentful" +subcategory: "" +description: |- + +--- + +# contentful_space (Resource) + + + +## Example Usage + +```terraform +resource "contentful_space" "example_space" { + name = "example_space_name" +} +``` + + +## Schema + +### Required + +- **name** (String) + +### Optional + +- **default_locale** (String) +- **id** (String) The ID of this resource. + +### Read-Only + +- **version** (Number) + + diff --git a/docs/resources/webhook.md b/docs/resources/webhook.md new file mode 100644 index 0000000..68f140d --- /dev/null +++ b/docs/resources/webhook.md @@ -0,0 +1,55 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "contentful_webhook Resource - terraform-provider-contentful" +subcategory: "" +description: |- + +--- + +# contentful_webhook (Resource) + + + +## Example Usage + +```terraform +resource "contentful_webhook" "example_webhook" { + space_id = "space-id" + + name = "webhook-name" + url= "https://www.example.com/test" + topics = [ + "Entry.create", + "ContentType.create", + ] + headers = { + header1 = "header1-value" + header2 = "header2-value" + } + http_basic_auth_username = "username" + http_basic_auth_password = "password" +} +``` + + +## Schema + +### Required + +- **name** (String) +- **space_id** (String) +- **topics** (List of String) +- **url** (String) + +### Optional + +- **headers** (Map of String) +- **http_basic_auth_password** (String) +- **http_basic_auth_username** (String) +- **id** (String) The ID of this resource. + +### Read-Only + +- **version** (Number) + + diff --git a/examples/resources/contentful_apikey/resource.tf b/examples/resources/contentful_apikey/resource.tf new file mode 100644 index 0000000..0f923fb --- /dev/null +++ b/examples/resources/contentful_apikey/resource.tf @@ -0,0 +1,6 @@ +resource "contentful_apikey" "myapikey" { + space_id = "space-id" + + name = "api-key-name" + description = "a-great-key" +} \ No newline at end of file diff --git a/examples/resources/contentful_asset/resource.tf b/examples/resources/contentful_asset/resource.tf new file mode 100644 index 0000000..0a5eb81 --- /dev/null +++ b/examples/resources/contentful_asset/resource.tf @@ -0,0 +1,23 @@ +resource "contentful_asset" "example_asset" { + asset_id = "test_asset" + locale = "en-US" + space_id = "space-id" + + fields { + title { + locale = "en-US" + content = "asset title" + } + description { + locale = "en-US" + content = "asset description" + } + file = { + upload = "https://images.ctfassets.net/fo9twyrwpveg/2VQx7vz73aMEYi20MMgCk0/66e502115b1f1f973a944b4bd2cc536f/IC-1H_Modern_Stack_Website.svg" + fileName = "example.jpeg" + contentType = "image/jpeg" + } + } + published = false + archived = false +} \ No newline at end of file diff --git a/examples/resources/contentful_contenttype/resource.tf b/examples/resources/contentful_contenttype/resource.tf new file mode 100644 index 0000000..f02e64e --- /dev/null +++ b/examples/resources/contentful_contenttype/resource.tf @@ -0,0 +1,30 @@ +resource "contentful_contenttype" "example_contenttype" { + space_id = "space-id" + name = "tf_linked" + description = "content type description" + display_field = "asset_field" + field { + id = "asset_field" + name = "Asset Field" + type = "Array" + items { + type = "Link" + link_type = "Asset" + } + required = true + } + field { + id = "entry_link_field" + name = "Entry Link Field" + type = "Link" + link_type = "Entry" + validations = [ + jsonencode({ + linkContentType = [ + contentful_contenttype.some_other_content_type.id + ] + }) + ] + required = false + } +} \ No newline at end of file diff --git a/examples/resources/contentful_entry/resource.tf b/examples/resources/contentful_entry/resource.tf new file mode 100644 index 0000000..315876f --- /dev/null +++ b/examples/resources/contentful_entry/resource.tf @@ -0,0 +1,19 @@ +resource "contentful_entry" "example_entry" { + entry_id = "mytestentry" + space_id = "space-id" + contenttype_id = "type-id" + locale = "en-US" + field { + id = "field1" + content = "Hello, World!" + locale = "en-US" + } + field { + id = "field2" + content = "Lettuce is healthy!" + locale = "en-US" + } + published = false + archived = false + depends_on = [contentful_contenttype.mycontenttype] +} \ No newline at end of file diff --git a/examples/resources/contentful_environment/resource.tf b/examples/resources/contentful_environment/resource.tf new file mode 100644 index 0000000..a84b097 --- /dev/null +++ b/examples/resources/contentful_environment/resource.tf @@ -0,0 +1,4 @@ +resource "contentful_environment" "example_environment" { + space_id = "spaced-id" + name = "environment-name" +} \ No newline at end of file diff --git a/examples/resources/contentful_locale/resource.tf b/examples/resources/contentful_locale/resource.tf new file mode 100644 index 0000000..896f3fb --- /dev/null +++ b/examples/resources/contentful_locale/resource.tf @@ -0,0 +1,10 @@ +resource "contentful_locale" "example_locale" { + space_id = "spaced-id" + + name = "locale-name" + code = "de" + fallback_code = "en-US" + optional = false + cda = false + cma = true +} \ No newline at end of file diff --git a/examples/resources/contentful_space/resource.tf b/examples/resources/contentful_space/resource.tf new file mode 100644 index 0000000..7c3568e --- /dev/null +++ b/examples/resources/contentful_space/resource.tf @@ -0,0 +1,3 @@ +resource "contentful_space" "example_space" { + name = "example_space_name" +} \ No newline at end of file diff --git a/examples/resources/contentful_webhook/resource.tf b/examples/resources/contentful_webhook/resource.tf new file mode 100644 index 0000000..e4fcce1 --- /dev/null +++ b/examples/resources/contentful_webhook/resource.tf @@ -0,0 +1,16 @@ +resource "contentful_webhook" "example_webhook" { + space_id = "space-id" + + name = "webhook-name" + url= "https://www.example.com/test" + topics = [ + "Entry.create", + "ContentType.create", + ] + headers = { + header1 = "header1-value" + header2 = "header2-value" + } + http_basic_auth_username = "username" + http_basic_auth_password = "password" +} \ No newline at end of file From 78f8d44b5717c2ade7326b5198d5e2ba880729f9 Mon Sep 17 00:00:00 2001 From: Fabian Heymann Date: Sun, 23 Jan 2022 15:18:06 +0100 Subject: [PATCH 092/192] feat: Update go version to 1.17 and use the terraform plugin SDK --- .github/workflows/go.yml | 8 +- .github/workflows/release.yml | 2 +- contentful/provider.go | 5 +- contentful/provider_test.go | 11 +- contentful/resource_contentful_apikey.go | 2 +- contentful/resource_contentful_apikey_test.go | 6 +- contentful/resource_contentful_asset.go | 2 +- contentful/resource_contentful_asset_test.go | 4 +- contentful/resource_contentful_contenttype.go | 2 +- .../resource_contentful_contenttype_test.go | 4 +- contentful/resource_contentful_entry.go | 2 +- contentful/resource_contentful_entry_test.go | 4 +- contentful/resource_contentful_environment.go | 2 +- .../resource_contentful_environment_test.go | 4 +- contentful/resource_contentful_locale.go | 2 +- contentful/resource_contentful_locale_test.go | 4 +- contentful/resource_contentful_space.go | 2 +- contentful/resource_contentful_space_test.go | 4 +- contentful/resource_contentful_webhook.go | 2 +- .../resource_contentful_webhook_test.go | 4 +- go.mod | 67 ++- go.sum | 556 +++++++++++------- main.go | 6 +- 23 files changed, 441 insertions(+), 264 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 5b709ae..ccc1c0d 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -12,10 +12,10 @@ jobs: name: Build runs-on: ubuntu-latest steps: - - name: Set up Go 1.14.2 + - name: Set up Go 1.17.6 uses: actions/setup-go@v1 with: - go-version: 1.14.2 + go-version: 1.17.6 id: go - name: Check out code into the Go module directory uses: actions/checkout@v2 @@ -33,10 +33,10 @@ jobs: runs-on: ubuntu-latest needs: [build] steps: - - name: Set up Go 1.14.2 + - name: Set up Go 1.17.6 uses: actions/setup-go@v1 with: - go-version: 1.14.2 + go-version: 1.17.6 id: go - name: Check out code into the Go module directory uses: actions/checkout@v2 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e97c501..a21aa74 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -14,7 +14,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v2 with: - go-version: 1.14 + go-version: 1.17 - name: Import GPG key id: import_gpg uses: paultyng/ghaction-import-gpg@v2.1.0 diff --git a/contentful/provider.go b/contentful/provider.go index e9e2224..0077450 100644 --- a/contentful/provider.go +++ b/contentful/provider.go @@ -1,13 +1,12 @@ package contentful import ( - "github.com/hashicorp/terraform/helper/schema" - "github.com/hashicorp/terraform/terraform" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" contentful "github.com/labd/contentful-go" ) // Provider returns the Terraform Provider as a scheme and makes resources reachable -func Provider() terraform.ResourceProvider { +func Provider() *schema.Provider { return &schema.Provider{ Schema: map[string]*schema.Schema{ "cma_token": { diff --git a/contentful/provider_test.go b/contentful/provider_test.go index 44bdb5a..c9bd83e 100644 --- a/contentful/provider_test.go +++ b/contentful/provider_test.go @@ -3,22 +3,21 @@ package contentful import ( "testing" - "github.com/hashicorp/terraform/helper/schema" - "github.com/hashicorp/terraform/terraform" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -var testAccProviders map[string]terraform.ResourceProvider +var testAccProviders map[string]*schema.Provider var testAccProvider *schema.Provider func init() { - testAccProvider = Provider().(*schema.Provider) - testAccProviders = map[string]terraform.ResourceProvider{ + testAccProvider = Provider() + testAccProviders = map[string]*schema.Provider{ "contentful": testAccProvider, } } func TestProvider(t *testing.T) { - if err := Provider().(*schema.Provider).InternalValidate(); err != nil { + if err := Provider().InternalValidate(); err != nil { t.Fatalf("err: %s", err) } } diff --git a/contentful/resource_contentful_apikey.go b/contentful/resource_contentful_apikey.go index 1e9dffa..dbf758d 100644 --- a/contentful/resource_contentful_apikey.go +++ b/contentful/resource_contentful_apikey.go @@ -1,7 +1,7 @@ package contentful import ( - "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" contentful "github.com/labd/contentful-go" ) diff --git a/contentful/resource_contentful_apikey_test.go b/contentful/resource_contentful_apikey_test.go index b8a3160..8102039 100644 --- a/contentful/resource_contentful_apikey_test.go +++ b/contentful/resource_contentful_apikey_test.go @@ -4,9 +4,9 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform/helper/acctest" - "github.com/hashicorp/terraform/helper/resource" - "github.com/hashicorp/terraform/terraform" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" contentful "github.com/labd/contentful-go" ) diff --git a/contentful/resource_contentful_asset.go b/contentful/resource_contentful_asset.go index d48036a..fa1d549 100644 --- a/contentful/resource_contentful_asset.go +++ b/contentful/resource_contentful_asset.go @@ -1,7 +1,7 @@ package contentful import ( - "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" contentful "github.com/labd/contentful-go" ) diff --git a/contentful/resource_contentful_asset_test.go b/contentful/resource_contentful_asset_test.go index b198af3..a0179b5 100644 --- a/contentful/resource_contentful_asset_test.go +++ b/contentful/resource_contentful_asset_test.go @@ -4,8 +4,8 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform/helper/resource" - "github.com/hashicorp/terraform/terraform" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" contentful "github.com/labd/contentful-go" ) diff --git a/contentful/resource_contentful_contenttype.go b/contentful/resource_contentful_contenttype.go index e160dcb..a687e7e 100644 --- a/contentful/resource_contentful_contenttype.go +++ b/contentful/resource_contentful_contenttype.go @@ -1,7 +1,7 @@ package contentful import ( - "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" contentful "github.com/labd/contentful-go" ) diff --git a/contentful/resource_contentful_contenttype_test.go b/contentful/resource_contentful_contenttype_test.go index 3cb80f7..2c075ce 100644 --- a/contentful/resource_contentful_contenttype_test.go +++ b/contentful/resource_contentful_contenttype_test.go @@ -4,8 +4,8 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform/helper/resource" - "github.com/hashicorp/terraform/terraform" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" contentful "github.com/labd/contentful-go" ) diff --git a/contentful/resource_contentful_entry.go b/contentful/resource_contentful_entry.go index 7c1e109..f8d3431 100644 --- a/contentful/resource_contentful_entry.go +++ b/contentful/resource_contentful_entry.go @@ -1,7 +1,7 @@ package contentful import ( - "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" contentful "github.com/labd/contentful-go" ) diff --git a/contentful/resource_contentful_entry_test.go b/contentful/resource_contentful_entry_test.go index 6c589a7..30c7cb7 100644 --- a/contentful/resource_contentful_entry_test.go +++ b/contentful/resource_contentful_entry_test.go @@ -4,8 +4,8 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform/helper/resource" - "github.com/hashicorp/terraform/terraform" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" contentful "github.com/labd/contentful-go" ) diff --git a/contentful/resource_contentful_environment.go b/contentful/resource_contentful_environment.go index d6f35d6..4f4b254 100644 --- a/contentful/resource_contentful_environment.go +++ b/contentful/resource_contentful_environment.go @@ -1,7 +1,7 @@ package contentful import ( - "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" contentful "github.com/labd/contentful-go" ) diff --git a/contentful/resource_contentful_environment_test.go b/contentful/resource_contentful_environment_test.go index c707d6d..2270bfc 100644 --- a/contentful/resource_contentful_environment_test.go +++ b/contentful/resource_contentful_environment_test.go @@ -4,8 +4,8 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform/helper/resource" - "github.com/hashicorp/terraform/terraform" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" contentful "github.com/labd/contentful-go" ) diff --git a/contentful/resource_contentful_locale.go b/contentful/resource_contentful_locale.go index 366f17f..f31e9c7 100644 --- a/contentful/resource_contentful_locale.go +++ b/contentful/resource_contentful_locale.go @@ -1,7 +1,7 @@ package contentful import ( - "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" contentful "github.com/labd/contentful-go" ) diff --git a/contentful/resource_contentful_locale_test.go b/contentful/resource_contentful_locale_test.go index 8afe7f3..107b539 100644 --- a/contentful/resource_contentful_locale_test.go +++ b/contentful/resource_contentful_locale_test.go @@ -4,8 +4,8 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform/helper/resource" - "github.com/hashicorp/terraform/terraform" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" contentful "github.com/labd/contentful-go" ) diff --git a/contentful/resource_contentful_space.go b/contentful/resource_contentful_space.go index eb77101..adfae00 100644 --- a/contentful/resource_contentful_space.go +++ b/contentful/resource_contentful_space.go @@ -1,7 +1,7 @@ package contentful import ( - "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" contentful "github.com/labd/contentful-go" ) diff --git a/contentful/resource_contentful_space_test.go b/contentful/resource_contentful_space_test.go index b82cdf8..0f51d30 100644 --- a/contentful/resource_contentful_space_test.go +++ b/contentful/resource_contentful_space_test.go @@ -4,8 +4,8 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform/helper/resource" - "github.com/hashicorp/terraform/terraform" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" contentful "github.com/labd/contentful-go" ) diff --git a/contentful/resource_contentful_webhook.go b/contentful/resource_contentful_webhook.go index fbb2351..6119e9d 100644 --- a/contentful/resource_contentful_webhook.go +++ b/contentful/resource_contentful_webhook.go @@ -1,7 +1,7 @@ package contentful import ( - "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" contentful "github.com/labd/contentful-go" ) diff --git a/contentful/resource_contentful_webhook_test.go b/contentful/resource_contentful_webhook_test.go index 16a39eb..5b0e1e4 100644 --- a/contentful/resource_contentful_webhook_test.go +++ b/contentful/resource_contentful_webhook_test.go @@ -4,8 +4,8 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform/helper/resource" - "github.com/hashicorp/terraform/terraform" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" contentful "github.com/labd/contentful-go" ) diff --git a/go.mod b/go.mod index 13c4914..5b57b60 100644 --- a/go.mod +++ b/go.mod @@ -1,8 +1,69 @@ module github.com/labd/terraform-provider-contentful -go 1.14 +go 1.17 + +require github.com/labd/contentful-go v0.5.0 require ( - github.com/hashicorp/terraform v0.12.24 - github.com/labd/contentful-go v0.5.0 + cloud.google.com/go v0.61.0 // indirect + cloud.google.com/go/storage v1.10.0 // indirect + github.com/agext/levenshtein v1.2.2 // indirect + github.com/apparentlymart/go-cidr v1.0.1 // indirect + github.com/apparentlymart/go-textseg v1.0.0 // indirect + github.com/aws/aws-sdk-go v1.25.3 // indirect + github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/fatih/color v1.7.0 // indirect + github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect + github.com/golang/protobuf v1.4.2 // indirect + github.com/google/go-cmp v0.5.2 // indirect + github.com/googleapis/gax-go/v2 v2.0.5 // indirect + github.com/hashicorp/errwrap v1.0.0 // indirect + github.com/hashicorp/go-checkpoint v0.5.0 // indirect + github.com/hashicorp/go-cleanhttp v0.5.1 // indirect + github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 // indirect + github.com/hashicorp/go-getter v1.5.0 // indirect + github.com/hashicorp/go-hclog v0.15.0 // indirect + github.com/hashicorp/go-multierror v1.0.0 // indirect + github.com/hashicorp/go-plugin v1.4.0 // indirect + github.com/hashicorp/go-safetemp v1.0.0 // indirect + github.com/hashicorp/go-uuid v1.0.1 // indirect + github.com/hashicorp/go-version v1.2.1 // indirect + github.com/hashicorp/hcl/v2 v2.3.0 // indirect + github.com/hashicorp/logutils v1.0.0 // indirect + github.com/hashicorp/terraform-exec v0.13.0 // indirect + github.com/hashicorp/terraform-json v0.8.0 // indirect + github.com/hashicorp/terraform-plugin-go v0.2.1 // indirect + github.com/hashicorp/terraform-plugin-sdk/v2 v2.4.3 + github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d // indirect + github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af // indirect + github.com/jstemmer/go-junit-report v0.9.1 // indirect + github.com/mattn/go-colorable v0.1.4 // indirect + github.com/mattn/go-isatty v0.0.10 // indirect + github.com/mitchellh/copystructure v1.0.0 // indirect + github.com/mitchellh/go-homedir v1.1.0 // indirect + github.com/mitchellh/go-testing-interface v1.0.4 // indirect + github.com/mitchellh/go-wordwrap v1.0.0 // indirect + github.com/mitchellh/mapstructure v1.1.2 // indirect + github.com/mitchellh/reflectwalk v1.0.1 // indirect + github.com/oklog/run v1.0.0 // indirect + github.com/ulikunitz/xz v0.5.8 // indirect + github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect + github.com/zclconf/go-cty v1.2.1 // indirect + go.opencensus.io v0.22.4 // indirect + golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 // indirect + golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect + golang.org/x/mod v0.3.0 // indirect + golang.org/x/net v0.0.0-20200707034311-ab3426394381 // indirect + golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d // indirect + golang.org/x/sys v0.0.0-20200523222454-059865788121 // indirect + golang.org/x/text v0.3.3 // indirect + golang.org/x/tools v0.0.0-20200713011307-fd294ab11aed // indirect + golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 // indirect + google.golang.org/api v0.29.0 // indirect + google.golang.org/appengine v1.6.6 // indirect + google.golang.org/genproto v0.0.0-20200711021454-869866162049 // indirect + google.golang.org/grpc v1.32.0 // indirect + google.golang.org/protobuf v1.25.0 // indirect + moul.io/http2curl v1.0.1-0.20190925090545-5cd742060b0e // indirect ) diff --git a/go.sum b/go.sum index 1c9388f..84b9936 100644 --- a/go.sum +++ b/go.sum @@ -3,346 +3,338 @@ cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -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 v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.61.0 h1:NLQf5e1OMspfNT1RAHOB3ublr1TW3YTXO8OiWwVjK2U= +cloud.google.com/go v0.61.0/go.mod h1:XukKJg4Y7QsUu0Hxg3qQKUWR4VuWivmyMK2+rUyxAqw= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= 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/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/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/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc= -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/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/go.mod h1:MgwOyqaIuKdG4TL/2ywSsIWKAfJfgHDo8ObuUk3t5sA= -github.com/Azure/go-autorest/autorest/validation v0.2.0/go.mod h1:3EEqHnBxQGHXRYq3HT1WyXAvT7LLY3tl70hw6tQIbjI= -github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= -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/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0 h1:STgFzyU5/8miMl0//zKh2aQeTyeaUH3WN9bSUiJ09bA= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= 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/go.mod h1:nuWgzSkT5PnyOd+272uUmV0dnAnAn42Mk7PiQC5VzN4= -github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409/go.mod h1:1pk82RBxDY/JZnPQrtqHlUFfCctgdorsd9M06fMynOM= -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/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/go.mod h1:T9M45xf79ahXVelWoOBmH0y4aC1t5kXO5BxwyakgIGA= -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/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/agl/ed25519 v0.0.0-20170116200512-5312a6153412/go.mod h1:WPjqKcmVOxf0XSf3YxCJs6N6AOSrOx3obionmG7T0y0= +github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= +github.com/andybalholm/crlf v0.0.0-20171020200849-670099aa064f/go.mod h1:k8feO4+kXDxro6ErPXBRTJ/ro2mf0SsFG8s7doP9kJE= +github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= 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= +github.com/apparentlymart/go-dump v0.0.0-20190214190832-042adf3cf4a0 h1:MzVXffFUye+ZcSR6opIgz9Co7WcDx6ZcY+RjfFHoA0I= 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/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= -github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec= 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/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= 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/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/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas= 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 h1:2bNwBOmhyFEFcoB3tGvTD5xanq+4kyOZlB8wFYbMjkk= -github.com/bmatcuk/doublestar v1.1.5/go.mod h1:wiQtGV+rzVYxB7WIlirSN++5HPtPlXEo9MEoZQC/PmE= -github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= 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/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/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/coreos/bbolt v1.3.0/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= -github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -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/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= 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/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -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/go.mod h1:w9KhXSgIyROl1DefbMYIE7UVSIvELTbMrCfx+QkYnoQ= -github.com/dylanmei/winrmtest v0.0.0-20190225150635-99b7fe2fddf1/go.mod h1:lcy9/2gH1jn/VCLouHA6tOEwLoNVd4GW6zhuKLmHC2Y= +github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg= +github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -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/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= +github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= +github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= +github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= +github.com/go-git/go-billy/v5 v5.0.0 h1:7NQHvd9FVid8VL4qVUMm8XifBK+2xCoZ2lSk0agRrHM= +github.com/go-git/go-billy/v5 v5.0.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= +github.com/go-git/go-git-fixtures/v4 v4.0.1/go.mod h1:m+ICp2rF3jDhFgEZ/8yziagdT1C+ZpZcrJjappBCDSw= +github.com/go-git/go-git/v5 v5.1.0 h1:HxJn9g/E7eYvKW3Fm7Jt4ee8LXfPOm/H1cdDu8vEssk= +github.com/go-git/go-git/v5 v5.1.0/go.mod h1:ZKfuPUoY1ZqIG4QG9BDBh3G4gLM5zvPuSJAozQrZuyM= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +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/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/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-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/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= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 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/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= 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/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +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/martian/v3 v3.0.0 h1:pMen7vLs8nvgEYhywH3KDWJIJTeEr2ULsVWHWYHQyBs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= -github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= 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/gophercloud/gophercloud v0.0.0-20190208042652-bc37892e1968/go.mod h1:3WdhXV3rUYy9p6AUW8d94kr+HS62Y4VL9mBnFxsD8q4= -github.com/gophercloud/utils v0.0.0-20190128072930-fbb6ab446f01/go.mod h1:wjDF8z83zTeg5eMLml5EBSlAhbF7G8DobyI1YsMuyzw= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -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/hashicorp/aws-sdk-go-base v0.4.0/go.mod h1:eRhlz3c4nhqxFZJAahJEFL7gh6Jyj5rQmQc7F9eHFyQ= -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/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= -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-cty v1.4.1-0.20200414143053-d3edf31b6320 h1:1/D3zfFHttUKaCaGKZ/dR2roBXv0vKbSCnssIldfQdI= +github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320/go.mod h1:EiZBMaudVLy8fmjf9Npq1dq9RalhveqZG5w/yz3mHWs= +github.com/hashicorp/go-getter v1.4.0/go.mod h1:7qxyCd8rBfcShwsvxgIguu4KbS3l8bUCwg2Umn7RjeY= +github.com/hashicorp/go-getter v1.5.0 h1:ciWJaeZWSMbc5OiLMpKp40MKFPqO44i0h3uyfXPBkkk= +github.com/hashicorp/go-getter v1.5.0/go.mod h1:a7z7NPPfNQpJWcn4rSWFtdrSldqLdLPEF3d8nFMsSLM= 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 h1:Yv9YzBlAETjy6AOX9eLBZ3nshNVRREgerT/3nvxlGho= -github.com/hashicorp/go-hclog v0.0.0-20181001195459-61d530d6c27f/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= -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-hclog v0.14.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= +github.com/hashicorp/go-hclog v0.15.0 h1:qMuK0wxsoW4D0ddCCYwPSTm4KQv1X1ke3WmPWZ0Mvsk= +github.com/hashicorp/go-hclog v0.15.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= 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 h1:hRho44SAoNu1CBtn5r8Q9J3rCs4ZverWZ4R+UeeNuWM= -github.com/hashicorp/go-plugin v1.0.1-0.20190610192547-a1bc61569a26/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/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-plugin v1.3.0/go.mod h1:F9eH4LrE/ZsRdbwhfjs9k9HoDUwAHnYtXdgmf1AVNs0= +github.com/hashicorp/go-plugin v1.4.0 h1:b0O7rs5uiJ99Iu9HugEzsM67afboErkHUWddUSpUO3A= +github.com/hashicorp/go-plugin v1.4.0/go.mod h1:5fGEH17QVwTTcR0zV7yhDPLLmFX9YSZ38b18Udy6vYQ= 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/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/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= -github.com/hashicorp/go-version v1.2.0 h1:3vNe/fWF5CBgRIguda1meWhsZHy3m8gCJ5wx+dIzX/E= -github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.2.1 h1:zEfKbn2+PDgroKdiOzqiE8rsmLqU2uwi5PB5pBJ3TkI= +github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/hcl v0.0.0-20170504190234-a4b07c25de5f h1:UdxlrJz4JOnY8W+DbLISwf2B8WXEolNRA8BGCwI9jws= -github.com/hashicorp/hcl v0.0.0-20170504190234-a4b07c25de5f/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w= -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/memberlist v0.1.0/go.mod h1:ncdBp14cuox2iFOq3kDiquKU6fqsTBc3W6JvZwjxxsE= -github.com/hashicorp/serf v0.0.0-20160124182025-e4ec8cc423bb/go.mod h1:h/Ru6tmZazX7WO/GDmwdpS975F019L4t5ng5IgwbNrE= -github.com/hashicorp/terraform v0.12.24 h1:lTTswsCcmTOhTwuUl2NdjtJBCNdGqZmRGQi0cjFHYOM= -github.com/hashicorp/terraform v0.12.24/go.mod h1:eJcloDEx5ywM4a1tetIuVrlqklM0bUVRYJBYAh4CYzA= -github.com/hashicorp/terraform-config-inspect v0.0.0-20191212124732-c6ae6269b9d7/go.mod h1:p+ivJws3dpqbp1iP84+npOyAmTTOLMgCzrXd3GSdn/A= -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 h1:b5rjCoWHc7eqmAS4/qyk21ZsHyb6Mxv/jykxvNTkU4M= +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/terraform-exec v0.13.0 h1:1Pth+pdWJAufJuWWjaVOVNEkoRTOjGn3hQpAqj4aPdg= +github.com/hashicorp/terraform-exec v0.13.0/go.mod h1:SGhto91bVRlgXQWcJ5znSz+29UZIa8kpBbkGwQ+g9E8= +github.com/hashicorp/terraform-json v0.8.0 h1:XObQ3PgqU52YLQKEaJ08QtUshAfN3yu4u8ebSW0vztc= +github.com/hashicorp/terraform-json v0.8.0/go.mod h1:3defM4kkMfttwiE7VakJDwCd4R+umhSQnvJwORXbprE= +github.com/hashicorp/terraform-plugin-go v0.2.1 h1:EW/R8bB2Zbkjmugzsy1d27yS8/0454b3MtYHkzOknqA= +github.com/hashicorp/terraform-plugin-go v0.2.1/go.mod h1:10V6F3taeDWVAoLlkmArKttR3IULlRWFAGtQIQTIDr4= +github.com/hashicorp/terraform-plugin-sdk/v2 v2.4.3 h1:DGnxpIYRHXQZb2TOlQ1OCEYxoRQrAcbLIcYm8kvbFuU= +github.com/hashicorp/terraform-plugin-sdk/v2 v2.4.3/go.mod h1:5wrrTcxbSaQXamCDbHZTHk6yTF9OEZaOvQ9fvLXBE3o= 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= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imdario/mergo v0.3.9 h1:UauaLniWCFHWd+Jp9oCEkTBj8VO/9DKg3PV3VCNMDIg= +github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jhump/protoreflect v1.6.0 h1:h5jfMVslIg6l29nsMs0D8Wj17RDVdNYti0vDN/PZZoE= +github.com/jhump/protoreflect v1.6.0/go.mod h1:eaTn3RZAmMBcV0fifFvlm6VHNz3wSkYyXYWUh7ymB74= 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/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= -github.com/joyent/triton-go v0.0.0-20180313100802-d8f9c0314926/go.mod h1:U+RSyWxWd04xTqnuOQxnai7XGS2PrPY2cfGoDKtMHjA= -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/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8= +github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd h1:Coekwdh0v2wtGp9Gmz1Ze3eVRAWJMLokvN3QjdzCHLY= +github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/keybase/go-crypto v0.0.0-20161004153544-93f5b35093ba/go.mod h1:ghbZscTyKdM07+Fw3KSi0hcJm+AlEUWj8QLlPtijN/M= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +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/labd/contentful-go v0.4.1-0.20201022091751-47d2076a5ad8 h1:gtVR7knJ1J9OFoLH4wfzCr8cvn27b1V3JVrXgCwE59c= -github.com/labd/contentful-go v0.4.1-0.20201022091751-47d2076a5ad8/go.mod h1:nU9FmlPmgIOwTWg2czqlpRMhPQplTaPuPjuz0oIcftM= github.com/labd/contentful-go v0.5.0 h1:nm7dHLDkNPZ6ZkxCoIy4Xo7/UcYsmJdOxS+SK8RIXhw= github.com/labd/contentful-go v0.5.0/go.mod h1:nU9FmlPmgIOwTWg2czqlpRMhPQplTaPuPjuz0oIcftM= -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/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/lusis/go-artifactory v0.0.0-20160115162124-7e4ce345df82/go.mod h1:y54tfGmO3NKssKveTEFFzH8C/akrSOy/iW9qEAUDV84= -github.com/masterzen/simplexml v0.0.0-20160608183007-4572e39b1ab9/go.mod h1:kCEbxUJlNDEBNbdQMkPSp6yaKcRXVI6f4ddk8Riv4bc= -github.com/masterzen/winrm v0.0.0-20190223112901-5e5c9a7fe54b/go.mod h1:wr1VqkwW0AB5JS0QLy5GpVMS9E3VtRoSYXUYyVk46KY= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg= -github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= +github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw= -github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +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/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= -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/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw= +github.com/mitchellh/cli v1.1.1/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= 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/go.mod h1:OaY7UOoTkkrX3wRwjpYRKafIkkyeD0UtweSHAWWiqQM= 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= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/go-testing-interface v1.0.4 h1:ZU1VNC02qyufSZsjjs7+khruk2fKvbQ3TwRV/IBCeFA= +github.com/mitchellh/go-testing-interface v1.0.4/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= 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/go.mod h1:pKvZHwWrZowLUzftuFq7coarnxbBXU4aQh3N0BJOeeA= -github.com/mitchellh/prefixedio v0.0.0-20190213213902-5733675afd51/go.mod h1:kB1naBgV9ORnkiTVeyJOI1DavaJkG4oNIq0Af6ZVKUo= -github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -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/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d/go.mod h1:YUTz3bUH2ZwIWBy3CJBeOBEugqcmXREj14T+iG/4k4U= +github.com/mitchellh/reflectwalk v1.0.1 h1:FVzMWA5RllMAKIdUSC8mdWo3XtwoecrH79BY70sEEpE= +github.com/mitchellh/reflectwalk v1.0.1/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +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/nsf/jsondiff v0.0.0-20200515183724-f29ed568f4ce h1:RPclfga2SEJmgMmz2k+Mg7cowZ8yv4Trqw9UsJby758= +github.com/nsf/jsondiff v0.0.0-20200515183724-f29ed568f4ce/go.mod h1:uFMI8w+ref4v2r9jz+c9i1IfIttS/OkmLfrk1jne5hs= github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= -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/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/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pkg/errors v0.8.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_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/common v0.2.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/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= -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/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -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/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= -github.com/spf13/afero v1.2.1 h1:qgMbHoJbPbw579P+1zVY+6n4nIFuIchaIjzZ/I/Yq8M= -github.com/spf13/afero v1.2.1/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= +github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.1.4/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/svanharmelen/jsonapi v0.0.0-20180618144545-0c0828c3f16d/go.mod h1:BSTlc8jOjh0niykqEGVXOLXdi9o0r0kR8tCYiMvjFgw= -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/go.mod h1:wk2XFUg6egk4tSDNZtXeKfe2G6690UVyt163PuUxBZk= -github.com/terraform-providers/terraform-provider-openstack v1.15.0/go.mod h1:2aQ6n/BtChAl1y2S60vebhyJyZXBsuAI5G4+lHrT1Ew= -github.com/tmc/grpc-websocket-proxy v0.0.0-20171017195756-830351dc03c6/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/ugorji/go v0.0.0-20180813092308-00b869d2f4a5/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ= -github.com/ulikunitz/xz v0.5.5 h1:pFrO0lVpTBXLpYw+pnLj6TbvHuyjXMfjGeCwSqCVwok= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/ulikunitz/xz v0.5.5/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8= +github.com/ulikunitz/xz v0.5.8 h1:ERv8V6GKqVi23rgu5cj9pVfVzJbOqAY2Ntl88O6c2nQ= +github.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= 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/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI= +github.com/vmihailenco/msgpack v4.0.4+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/xlab/treeprint v0.0.0-20161029104018-1d6e34225557/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/zclconf/go-cty v1.0.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s= -github.com/zclconf/go-cty v1.1.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8= github.com/zclconf/go-cty v1.2.1 h1:vGMsygfmeCl4Xb6OA5U5XVAaQZ69FvoG7X2jUtQujb8= github.com/zclconf/go-cty v1.2.1/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8= -github.com/zclconf/go-cty-yaml v1.0.1 h1:up11wlgAaDvlAGENcFDnZgkn0qUJurso7k6EpURKNF8= -github.com/zclconf/go-cty-yaml v1.0.1/go.mod h1:IP3Ylp0wQpYm50IHK8OZWKMu6sPJIUgKa8XhiVHura0= +github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8= 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/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4 h1:LYy1Hy3MJdrCdMwwzxA/dRok4ejH+RwNGbuoD9fCjto= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= 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= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/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-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/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-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180530234432-1e491301e022/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -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= @@ -350,25 +342,38 @@ golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= 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/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-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/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-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/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= @@ -379,13 +384,33 @@ golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190804053845-51ab0e2deafa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121 h1:rITEj+UZHYC927n8GT97eC3zrpzXdb/voyeOuVKS46o= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -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/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -394,48 +419,141 @@ golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200507205054-480da3ebd79c/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200713011307-fd294ab11aed h1:+qzWo37K31KxduIYaBeMqJ8MUOyTayOQKpH9aDPLMSY= +golang.org/x/tools v0.0.0-20200713011307-fd294ab11aed/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.9.0 h1:jbyannxz0XFD3zdjgrSUsaJbgpH4eTrkdhRChkHPfO8= google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0 h1:BaiDisFir8O4IJxvAabCGGkQ6yCJegNQqSVoYUNAnbk= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20170818010345-ee236bd376b0/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200711021454-869866162049 h1:YFTFpQhgvrLrmxtiIncJxFXeCyq84ixuKWVCaCAi9Oc= +google.golang.org/genproto v0.0.0-20200711021454-869866162049/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.1 h1:j6XxA85m/6txkUCHvzlV5f+HBNl/1r5cZ2A/3IEFOO8= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.32.0 h1:zWTV+LMdc3kaiJMSTOFz2UgSBgx8RNQoTGiZu3fR9S0= +google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/cheggaaa/pb.v1 v1.0.27/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= -gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= moul.io/http2curl v1.0.1-0.20190925090545-5cd742060b0e h1:C7q+e9M5nggAvWfVg9Nl66kebKeuJlP3FD58V4RR5wo= moul.io/http2curl v1.0.1-0.20190925090545-5cd742060b0e/go.mod h1:nejbQVfXh96n9dSF6cH3Jsk/QI1Z2oEL7sSI2ifXFNA= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/main.go b/main.go index a2e9b51..d2ebe8b 100644 --- a/main.go +++ b/main.go @@ -1,14 +1,14 @@ package main import ( - "github.com/hashicorp/terraform/plugin" - "github.com/hashicorp/terraform/terraform" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/plugin" "github.com/labd/terraform-provider-contentful/contentful" ) func main() { plugin.Serve(&plugin.ServeOpts{ - ProviderFunc: func() terraform.ResourceProvider { + ProviderFunc: func() *schema.Provider { return contentful.Provider() }, }) From 3cf6699719c8ffe6711a3040414803f714db0889 Mon Sep 17 00:00:00 2001 From: Fabian Heymann Date: Sun, 23 Jan 2022 21:16:45 +0100 Subject: [PATCH 093/192] feat: Compatibility with terraform standards and SDK v2 --- contentful/resource_contentful_asset.go | 111 +++++++++++------- contentful/resource_contentful_asset_test.go | 12 +- .../resource_contentful_contenttype_test.go | 58 ++++----- contentful/resource_contentful_locale_test.go | 6 +- docs/resources/asset.md | 6 +- docs/resources/webhook.md | 2 +- 6 files changed, 113 insertions(+), 82 deletions(-) diff --git a/contentful/resource_contentful_asset.go b/contentful/resource_contentful_asset.go index fa1d549..b7b6a22 100644 --- a/contentful/resource_contentful_asset.go +++ b/contentful/resource_contentful_asset.go @@ -1,6 +1,9 @@ package contentful import ( + "fmt" + "time" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" contentful "github.com/labd/contentful-go" ) @@ -67,17 +70,18 @@ func resourceContentfulAsset() *schema.Resource { }, }, "file": { - Type: schema.TypeMap, + Type: schema.TypeList, Required: true, + MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "url": { Type: schema.TypeString, - Optional: true, + Computed: true, }, "upload": { Type: schema.TypeString, - Optional: true, + Required: true, }, "details": { Type: schema.TypeSet, @@ -107,15 +111,15 @@ func resourceContentfulAsset() *schema.Resource { }, }, }, - "uploadFrom": { + "upload_from": { Type: schema.TypeString, Computed: true, }, - "fileName": { + "file_name": { Type: schema.TypeString, - Computed: true, + Required: true, }, - "contentType": { + "content_type": { Type: schema.TypeString, Required: true, }, @@ -156,7 +160,13 @@ func resourceCreateAsset(d *schema.ResourceData, m interface{}) (err error) { localizedDescription[field["locale"].(string)] = field["content"].(string) } - file := fields["file"].(map[string]interface{}) + files := fields["file"].([]interface{}) + + if len(files) == 0 { + return fmt.Errorf("file block not defined in asset") + } + + file := files[0].(map[string]interface{}) asset := &contentful.Asset{ Sys: &contentful.Sys{ @@ -169,36 +179,38 @@ func resourceCreateAsset(d *schema.ResourceData, m interface{}) (err error) { Description: localizedDescription, File: map[string]*contentful.File{ d.Get("locale").(string): { - FileName: file["fileName"].(string), - ContentType: file["contentType"].(string), + FileName: file["file_name"].(string), + ContentType: file["content_type"].(string), }, }, }, } - if url, ok := file["url"].(string); ok { + if url, ok := file["url"].(string); ok && url != "" { asset.Fields.File[d.Get("locale").(string)].URL = url } - if upload, ok := file["upload"].(string); ok { + if upload, ok := file["upload"].(string); ok && upload != "" { asset.Fields.File[d.Get("locale").(string)].UploadURL = upload } - if details, ok := file["fileDetails"].(*contentful.FileDetails); ok { + if details, ok := file["file_details"].(*contentful.FileDetails); ok { asset.Fields.File[d.Get("locale").(string)].Details = details } - if uploadFrom, ok := file["uploadFrom"].(string); ok { - asset.Fields.File[d.Get("locale").(string)].UploadFrom.Sys.ID = uploadFrom + if uploadFrom, ok := file["upload_from"].(string); ok && uploadFrom != "" { + asset.Fields.File[d.Get("locale").(string)].UploadFrom = &contentful.UploadFrom{ + Sys: &contentful.Sys{ + ID: uploadFrom, + }, + } } - err = client.Assets.Upsert(d.Get("space_id").(string), asset) - if err != nil { + if err = client.Assets.Upsert(d.Get("space_id").(string), asset); err != nil { return err } - err = client.Assets.Process(d.Get("space_id").(string), asset) - if err != nil { + if err = client.Assets.Process(d.Get("space_id").(string), asset); err != nil { return err } @@ -208,8 +220,9 @@ func resourceCreateAsset(d *schema.ResourceData, m interface{}) (err error) { return err } - err = setAssetState(d, m) - if err != nil { + time.Sleep(1 * time.Second) // avoid race conditions with version mismatches + + if err = setAssetState(d, m); err != nil { return err } @@ -221,7 +234,7 @@ func resourceUpdateAsset(d *schema.ResourceData, m interface{}) (err error) { spaceID := d.Get("space_id").(string) assetID := d.Id() - asset, err := client.Assets.Get(spaceID, assetID) + _, err = client.Assets.Get(spaceID, assetID) if err != nil { return err } @@ -242,9 +255,15 @@ func resourceUpdateAsset(d *schema.ResourceData, m interface{}) (err error) { localizedDescription[field["locale"].(string)] = field["content"].(string) } - file := fields["file"].(map[string]interface{}) + files := fields["file"].([]interface{}) + + if len(files) == 0 { + return fmt.Errorf("file block not defined in asset") + } + + file := files[0].(map[string]interface{}) - asset = &contentful.Asset{ + asset := &contentful.Asset{ Sys: &contentful.Sys{ ID: d.Get("asset_id").(string), Version: d.Get("version").(int), @@ -255,36 +274,38 @@ func resourceUpdateAsset(d *schema.ResourceData, m interface{}) (err error) { Description: localizedDescription, File: map[string]*contentful.File{ d.Get("locale").(string): { - FileName: file["fileName"].(string), - ContentType: file["contentType"].(string), + FileName: file["file_name"].(string), + ContentType: file["content_type"].(string), }, }, }, } - if url, ok := file["url"].(string); ok { + if url, ok := file["url"].(string); ok && url != "" { asset.Fields.File[d.Get("locale").(string)].URL = url } - if upload, ok := file["upload"].(string); ok { + if upload, ok := file["upload"].(string); ok && upload != "" { asset.Fields.File[d.Get("locale").(string)].UploadURL = upload } - if details, ok := file["fileDetails"].(*contentful.FileDetails); ok { + if details, ok := file["file_details"].(*contentful.FileDetails); ok { asset.Fields.File[d.Get("locale").(string)].Details = details } - if uploadFrom, ok := file["uploadFrom"].(string); ok { - asset.Fields.File[d.Get("locale").(string)].UploadFrom.Sys.ID = uploadFrom + if uploadFrom, ok := file["upload_from"].(string); ok && uploadFrom != "" { + asset.Fields.File[d.Get("locale").(string)].UploadFrom = &contentful.UploadFrom{ + Sys: &contentful.Sys{ + ID: uploadFrom, + }, + } } - err = client.Assets.Upsert(d.Get("space_id").(string), asset) - if err != nil { + if err := client.Assets.Upsert(d.Get("space_id").(string), asset); err != nil { return err } - err = client.Assets.Process(d.Get("space_id").(string), asset) - if err != nil { + if err = client.Assets.Process(d.Get("space_id").(string), asset); err != nil { return err } @@ -294,8 +315,7 @@ func resourceUpdateAsset(d *schema.ResourceData, m interface{}) (err error) { return err } - err = setAssetState(d, m) - if err != nil { + if err = setAssetState(d, m); err != nil { return err } @@ -310,19 +330,26 @@ func setAssetState(d *schema.ResourceData, m interface{}) (err error) { asset, _ := client.Assets.Get(spaceID, assetID) if d.Get("published").(bool) && asset.Sys.PublishedAt == "" { - err = client.Assets.Publish(spaceID, asset) + if err = client.Assets.Publish(spaceID, asset); err != nil { + return err + } } else if !d.Get("published").(bool) && asset.Sys.PublishedAt != "" { - err = client.Assets.Unpublish(spaceID, asset) + if err = client.Assets.Unpublish(spaceID, asset); err != nil { + return err + } } if d.Get("archived").(bool) && asset.Sys.ArchivedAt == "" { - err = client.Assets.Archive(spaceID, asset) + if err = client.Assets.Archive(spaceID, asset); err != nil { + return err + } } else if !d.Get("archived").(bool) && asset.Sys.ArchivedAt != "" { - err = client.Assets.Unarchive(spaceID, asset) + if err = client.Assets.Unarchive(spaceID, asset); err != nil { + return err + } } err = setAssetProperties(d, asset) - return err } diff --git a/contentful/resource_contentful_asset_test.go b/contentful/resource_contentful_asset_test.go index a0179b5..3f0eede 100644 --- a/contentful/resource_contentful_asset_test.go +++ b/contentful/resource_contentful_asset_test.go @@ -121,10 +121,10 @@ resource "contentful_asset" "myasset" { locale = "en-US" content = "Asset description" } - file = { + file { upload = "https://images.ctfassets.net/fo9twyrwpveg/2VQx7vz73aMEYi20MMgCk0/66e502115b1f1f973a944b4bd2cc536f/IC-1H_Modern_Stack_Website.svg" - fileName = "example.jpeg" - contentType = "image/jpeg" + file_name = "example.jpeg" + content_type = "image/jpeg" } } published = true @@ -146,10 +146,10 @@ resource "contentful_asset" "myasset" { locale = "en-US" content = "Updated asset description" } - file = { + file { upload = "https://images.ctfassets.net/fo9twyrwpveg/2VQx7vz73aMEYi20MMgCk0/66e502115b1f1f973a944b4bd2cc536f/IC-1H_Modern_Stack_Website.svg" - fileName = "example.jpeg" - contentType = "image/jpeg" + file_name = "example.jpeg" + content_type = "image/jpeg" } } published = false diff --git a/contentful/resource_contentful_contenttype_test.go b/contentful/resource_contentful_contenttype_test.go index 2c075ce..10d4cc3 100644 --- a/contentful/resource_contentful_contenttype_test.go +++ b/contentful/resource_contentful_contenttype_test.go @@ -122,22 +122,22 @@ resource "contentful_contenttype" "mycontenttype" { description = "Terraform Acc Test Content Type description change" display_field = "field1" field { - disabled = false - id = "field1" - localized = false - name = "Field 1 name change" - omitted = false - required = true - type = "Text" + disabled = false + id = "field1" + localized = false + name = "Field 1 name change" + omitted = false + required = true + type = "Text" } field { - disabled = false - id = "field3" - localized = false - name = "Field 3 new field" - omitted = false - required = true - type = "Integer" + disabled = false + id = "field3" + localized = false + name = "Field 3 new field" + omitted = false + required = true + type = "Integer" } } ` @@ -149,22 +149,22 @@ resource "contentful_contenttype" "mycontenttype" { description = "Terraform Acc Test Content Type description change" display_field = "field1" field { - disabled = false - id = "field1" - localized = false - name = "Field 1 name change" - omitted = false - required = true - type = "Text" + disabled = false + id = "field1" + localized = false + name = "Field 1 name change" + omitted = false + required = true + type = "Text" } field { - disabled = false - id = "field3" - localized = false - name = "Field 3 new field" - omitted = false - required = true - type = "Integer" + disabled = false + id = "field3" + localized = false + name = "Field 3 new field" + omitted = false + required = true + type = "Integer" } } @@ -191,7 +191,7 @@ resource "contentful_contenttype" "mylinked_contenttype" { validations = [ jsonencode({ linkContentType = [ - contentful_contenttype.mycontenttype.id + contentful_contenttype.mycontenttype.id ] }) ] diff --git a/contentful/resource_contentful_locale_test.go b/contentful/resource_contentful_locale_test.go index 107b539..041d507 100644 --- a/contentful/resource_contentful_locale_test.go +++ b/contentful/resource_contentful_locale_test.go @@ -1,6 +1,7 @@ package contentful import ( + "encoding/json" "fmt" "testing" @@ -136,7 +137,10 @@ func testAccContentfulLocaleDestroy(s *terraform.State) error { client := testAccProvider.Meta().(*contentful.Client) _, err := client.Locales.Get(spaceID, localeID) - if _, ok := err.(contentful.NotFoundError); ok { + + // This is caused by a bug in the client library that tries to cast + // error.details to a map but it is a string in this case + if _, ok := err.(*json.UnmarshalTypeError); ok { return nil } diff --git a/docs/resources/asset.md b/docs/resources/asset.md index 602b68a..19a8744 100644 --- a/docs/resources/asset.md +++ b/docs/resources/asset.md @@ -27,10 +27,10 @@ resource "contentful_asset" "example_asset" { locale = "en-US" content = "asset description" } - file = { + file { upload = "https://images.ctfassets.net/fo9twyrwpveg/2VQx7vz73aMEYi20MMgCk0/66e502115b1f1f973a944b4bd2cc536f/IC-1H_Modern_Stack_Website.svg" - fileName = "example.jpeg" - contentType = "image/jpeg" + file_name = "example.jpeg" + content_type = "image/jpeg" } } published = false diff --git a/docs/resources/webhook.md b/docs/resources/webhook.md index 68f140d..db2e410 100644 --- a/docs/resources/webhook.md +++ b/docs/resources/webhook.md @@ -17,7 +17,7 @@ resource "contentful_webhook" "example_webhook" { space_id = "space-id" name = "webhook-name" - url= "https://www.example.com/test" + url = "https://www.example.com/test" topics = [ "Entry.create", "ContentType.create", From 1c6b11fdcb76e02f1eb9bdc3c4cf17958060e2c1 Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Wed, 8 Apr 2020 16:29:50 +0200 Subject: [PATCH 094/192] local-setup --- Dockerfile-test | 6 +-- constants.go | 11 +++--- install-dependencies.sh | 2 +- provider.go | 6 +-- provider_test.go | 2 +- resource_contentful_apikey.go | 18 ++++----- resource_contentful_apikey_test.go | 6 +-- resource_contentful_contenttype.go | 52 ++++++++++++------------- resource_contentful_contenttype_test.go | 22 +++++------ resource_contentful_locale.go | 26 ++++++------- resource_contentful_locale_test.go | 34 ++++++++-------- resource_contentful_space.go | 16 ++++---- resource_contentful_space_test.go | 10 ++--- resource_contentful_webhook.go | 28 ++++++------- resource_contentful_webhook_test.go | 36 ++++++++--------- 15 files changed, 138 insertions(+), 137 deletions(-) diff --git a/Dockerfile-test b/Dockerfile-test index 5e5a912..72b719c 100644 --- a/Dockerfile-test +++ b/Dockerfile-test @@ -1,11 +1,11 @@ FROM golang:1.9 -WORKDIR /go/src/github.com/danihodovic/contentful-terraform +WORKDIR /go/src/github.com/labd/terraform-contentful # http://stackoverflow.com/questions/39278756/cache-go-get-in-docker-build -COPY ./install-dependencies.sh /go/src/github.com/danihodovic/contentful-terraform/ +COPY ./install-dependencies.sh /go/src/github.com/labd/terraform-contentful RUN ./install-dependencies.sh -COPY . /go/src/github.com/danihodovic/contentful-terraform +COPY . /go/src/github.com/labd/terraform-contentful CMD go test -v diff --git a/constants.go b/constants.go index 5c8f977..5ea01bd 100644 --- a/constants.go +++ b/constants.go @@ -4,13 +4,14 @@ import ( "errors" ) +// noinspection GoUnusedGlobalVariable var ( baseURL = "https://api.contentful.com" contentfulContentType = "application/vnd.contentful.management.v1+json" // User friendly errors we return - errorUnauthorized = errors.New("401 Unauthorized. Is the CMA token valid?") - errorSpaceNotFound = errors.New("Space not found") - errorOrganizationNotFound = errors.New("Organization not found") - errorLocaleNotFound = errors.New("Locale not found") - errorWebhookNotFound = errors.New("The webhook could not be found") + errorUnauthorized = errors.New("401 Unauthorized. Is the CMA token valid") + errorSpaceNotFound = errors.New("space not found") + errorOrganizationNotFound = errors.New("organization not found") + errorLocaleNotFound = errors.New("locale not found") + errorWebhookNotFound = errors.New("the webhook could not be found") ) diff --git a/install-dependencies.sh b/install-dependencies.sh index 656d26a..64a0a61 100755 --- a/install-dependencies.sh +++ b/install-dependencies.sh @@ -4,4 +4,4 @@ go get github.com/hashicorp/terraform/terraform go get github.com/hashicorp/terraform/helper/resource go get github.com/hashicorp/terraform/helper/schema -go get github.com/tolgaakyuz/contentful-go +go get github.com/labd/contentful-go diff --git a/provider.go b/provider.go index 9e47ad8..945fd71 100644 --- a/provider.go +++ b/provider.go @@ -5,20 +5,20 @@ import ( "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/terraform" - contentful "github.com/tolgaakyuz/contentful-go" + contentful "github.com/labd/contentful-go" ) // Provider does shit func Provider() terraform.ResourceProvider { return &schema.Provider{ Schema: map[string]*schema.Schema{ - "cma_token": &schema.Schema{ + "cma_token": { Type: schema.TypeString, Required: true, DefaultFunc: schema.EnvDefaultFunc("CONTENTFUL_MANAGEMENT_TOKEN", nil), Description: "The Contentful Management API token", }, - "organization_id": &schema.Schema{ + "organization_id": { Type: schema.TypeString, Required: true, DefaultFunc: schema.EnvDefaultFunc("CONTENTFUL_ORGANIZATION_ID", nil), diff --git a/provider_test.go b/provider_test.go index 2ca91c1..8ff6fb1 100644 --- a/provider_test.go +++ b/provider_test.go @@ -25,7 +25,7 @@ func TestProvider(t *testing.T) { } func TestProvider_impl(t *testing.T) { - var _ terraform.ResourceProvider = Provider() + var _ = Provider() } func testAccPreCheck(t *testing.T) { diff --git a/resource_contentful_apikey.go b/resource_contentful_apikey.go index 1874f53..7d3b787 100644 --- a/resource_contentful_apikey.go +++ b/resource_contentful_apikey.go @@ -2,7 +2,7 @@ package main import ( "github.com/hashicorp/terraform/helper/schema" - contentful "github.com/tolgaakyuz/contentful-go" + contentful "github.com/labd/contentful-go" ) func resourceContentfulAPIKey() *schema.Resource { @@ -13,19 +13,19 @@ func resourceContentfulAPIKey() *schema.Resource { Delete: resourceDeleteAPIKey, Schema: map[string]*schema.Schema{ - "version": &schema.Schema{ + "version": { Type: schema.TypeInt, Computed: true, }, - "space_id": &schema.Schema{ + "space_id": { Type: schema.TypeString, Required: true, }, - "name": &schema.Schema{ + "name": { Type: schema.TypeString, Required: true, }, - "description": &schema.Schema{ + "description": { Type: schema.TypeString, Optional: true, }, @@ -34,7 +34,7 @@ func resourceContentfulAPIKey() *schema.Resource { } func resourceCreateAPIKey(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Contentful) + client := m.(*contentful.Client) apiKey := &contentful.APIKey{ Name: d.Get("name").(string), @@ -56,7 +56,7 @@ func resourceCreateAPIKey(d *schema.ResourceData, m interface{}) (err error) { } func resourceUpdateAPIKey(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Contentful) + client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) apiKeyID := d.Id() @@ -83,7 +83,7 @@ func resourceUpdateAPIKey(d *schema.ResourceData, m interface{}) (err error) { } func resourceReadAPIKey(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Contentful) + client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) apiKeyID := d.Id() @@ -97,7 +97,7 @@ func resourceReadAPIKey(d *schema.ResourceData, m interface{}) (err error) { } func resourceDeleteAPIKey(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Contentful) + client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) apiKeyID := d.Id() diff --git a/resource_contentful_apikey_test.go b/resource_contentful_apikey_test.go index bc1542a..5531c69 100644 --- a/resource_contentful_apikey_test.go +++ b/resource_contentful_apikey_test.go @@ -7,7 +7,7 @@ import ( "github.com/hashicorp/terraform/helper/acctest" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" - contentful "github.com/tolgaakyuz/contentful-go" + contentful "github.com/labd/contentful-go" ) func TestAccContentfulAPIKey_Basic(t *testing.T) { @@ -63,7 +63,7 @@ func testAccCheckContentfulAPIKeyExists(n string, apiKey *contentful.APIKey) res return fmt.Errorf("No api key ID is set") } - client := testAccProvider.Meta().(*contentful.Contentful) + client := testAccProvider.Meta().(*contentful.Client) contentfulAPIKey, err := client.APIKeys.Get(spaceID, apiKeyID) if err != nil { @@ -109,7 +109,7 @@ func testAccContentfulAPIKeyDestroy(s *terraform.State) error { return fmt.Errorf("No apikey ID is set") } - client := testAccProvider.Meta().(*contentful.Contentful) + client := testAccProvider.Meta().(*contentful.Client) _, err := client.APIKeys.Get(spaceID, apiKeyID) if _, ok := err.(contentful.NotFoundError); ok { diff --git a/resource_contentful_contenttype.go b/resource_contentful_contenttype.go index bee476a..b261ba7 100644 --- a/resource_contentful_contenttype.go +++ b/resource_contentful_contenttype.go @@ -2,7 +2,7 @@ package main import ( "github.com/hashicorp/terraform/helper/schema" - contentful "github.com/tolgaakyuz/contentful-go" + contentful "github.com/labd/contentful-go" ) func resourceContentfulContentType() *schema.Resource { @@ -13,93 +13,93 @@ func resourceContentfulContentType() *schema.Resource { Delete: resourceContentTypeDelete, Schema: map[string]*schema.Schema{ - "space_id": &schema.Schema{ + "space_id": { Type: schema.TypeString, Required: true, ForceNew: true, }, - "version": &schema.Schema{ + "version": { Type: schema.TypeInt, Computed: true, }, - "name": &schema.Schema{ + "name": { Type: schema.TypeString, Required: true, }, - "description": &schema.Schema{ + "description": { Type: schema.TypeString, Optional: true, }, - "display_field": &schema.Schema{ + "display_field": { Type: schema.TypeString, Required: true, }, - "field": &schema.Schema{ + "field": { Type: schema.TypeSet, Required: true, MinItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ - "id": &schema.Schema{ + "id": { Type: schema.TypeString, Required: true, }, - "name": &schema.Schema{ + "name": { Type: schema.TypeString, Required: true, }, //@TODO Add ValidateFunc to validate field type - "type": &schema.Schema{ + "type": { Type: schema.TypeString, Required: true, }, - "link_type": &schema.Schema{ + "link_type": { Type: schema.TypeString, Optional: true, }, - "items": &schema.Schema{ + "items": { Type: schema.TypeSet, Optional: true, MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ - "type": &schema.Schema{ + "type": { Type: schema.TypeString, Required: true, }, - "validations": &schema.Schema{ + "validations": { Type: schema.TypeList, Optional: true, Elem: &schema.Schema{Type: schema.TypeString}, }, - "link_type": &schema.Schema{ + "link_type": { Type: schema.TypeString, Required: true, }, }, }, }, - "required": &schema.Schema{ + "required": { Type: schema.TypeBool, Optional: true, Default: false, }, - "localized": &schema.Schema{ + "localized": { Type: schema.TypeBool, Optional: true, Default: false, }, - "disabled": &schema.Schema{ + "disabled": { Type: schema.TypeBool, Optional: true, Default: false, }, - "omitted": &schema.Schema{ + "omitted": { Type: schema.TypeBool, Optional: true, Default: false, }, - "validations": &schema.Schema{ + "validations": { Type: schema.TypeList, Optional: true, Elem: &schema.Schema{Type: schema.TypeString}, @@ -112,7 +112,7 @@ func resourceContentfulContentType() *schema.Resource { } func resourceContentTypeCreate(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Contentful) + client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) ct := &contentful.ContentType{ @@ -177,7 +177,7 @@ func resourceContentTypeCreate(d *schema.ResourceData, m interface{}) (err error } func resourceContentTypeRead(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Contentful) + client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) _, err = client.ContentTypes.Get(spaceID, d.Id()) @@ -189,7 +189,7 @@ func resourceContentTypeUpdate(d *schema.ResourceData, m interface{}) (err error var existingFields []*contentful.Field var deletedFields []*contentful.Field - client := m.(*contentful.Contentful) + client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) ct, err := client.ContentTypes.Get(spaceID, d.Id()) @@ -205,9 +205,9 @@ func resourceContentTypeUpdate(d *schema.ResourceData, m interface{}) (err error } if d.HasChange("field") { - old, new := d.GetChange("field") + old, nw := d.GetChange("field") - existingFields, deletedFields = checkFieldChanges(old.(*schema.Set), new.(*schema.Set)) + existingFields, deletedFields = checkFieldChanges(old.(*schema.Set), nw.(*schema.Set)) ct.Fields = existingFields @@ -245,7 +245,7 @@ func resourceContentTypeUpdate(d *schema.ResourceData, m interface{}) (err error } func resourceContentTypeDelete(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Contentful) + client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) ct, err := client.ContentTypes.Get(spaceID, d.Id()) diff --git a/resource_contentful_contenttype_test.go b/resource_contentful_contenttype_test.go index cd1fcc5..5900087 100644 --- a/resource_contentful_contenttype_test.go +++ b/resource_contentful_contenttype_test.go @@ -6,7 +6,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" - contentful "github.com/tolgaakyuz/contentful-go" + contentful "github.com/labd/contentful-go" ) func TestAccContentfulContentType_Basic(t *testing.T) { @@ -15,17 +15,17 @@ func TestAccContentfulContentType_Basic(t *testing.T) { Providers: testAccProviders, CheckDestroy: testAccCheckContentfulContentTypeDestroy, Steps: []resource.TestStep{ - resource.TestStep{ + { Config: testAccContentfulContentTypeConfig, Check: resource.TestCheckResourceAttr( "contentful_contenttype.mycontenttype", "name", "TF Acc Test CT 1"), }, - resource.TestStep{ + { Config: testAccContentfulContentTypeUpdateConfig, Check: resource.TestCheckResourceAttr( "contentful_contenttype.mycontenttype", "name", "TF Acc Test CT name change"), }, - resource.TestStep{ + { Config: testAccContentfulContentTypeLinkConfig, Check: resource.TestCheckResourceAttr( "contentful_contenttype.mylinked_contenttype", "name", "TF Acc Test Linked CT"), @@ -38,19 +38,19 @@ func testAccCheckContentfulContentTypeExists(n string, contentType *contentful.C return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] if !ok { - return fmt.Errorf("Not found %s", n) + return fmt.Errorf("not found %s", n) } if rs.Primary.ID == "" { - return fmt.Errorf("No content type ID is set") + return fmt.Errorf("no content type ID is set") } spaceID := rs.Primary.Attributes["space_id"] if spaceID == "" { - return fmt.Errorf("No space_id is set") + return fmt.Errorf("no space_id is set") } - client := testAccProvider.Meta().(*contentful.Contentful) + client := testAccProvider.Meta().(*contentful.Client) ct, err := client.ContentTypes.Get(spaceID, rs.Primary.ID) if err != nil { @@ -71,17 +71,17 @@ func testAccCheckContentfulContentTypeDestroy(s *terraform.State) (err error) { spaceID := rs.Primary.Attributes["space_id"] if spaceID == "" { - return fmt.Errorf("No space_id is set") + return fmt.Errorf("no space_id is set") } - client := testAccProvider.Meta().(*contentful.Contentful) + client := testAccProvider.Meta().(*contentful.Client) _, err := client.ContentTypes.Get(spaceID, rs.Primary.ID) if _, ok := err.(contentful.NotFoundError); ok { return nil } - return fmt.Errorf("Content Type still exists with id: %s", rs.Primary.ID) + return fmt.Errorf("content Type still exists with id: %s", rs.Primary.ID) } return nil diff --git a/resource_contentful_locale.go b/resource_contentful_locale.go index 9983222..1c51b50 100644 --- a/resource_contentful_locale.go +++ b/resource_contentful_locale.go @@ -2,7 +2,7 @@ package main import ( "github.com/hashicorp/terraform/helper/schema" - contentful "github.com/tolgaakyuz/contentful-go" + contentful "github.com/labd/contentful-go" ) func resourceContentfulLocale() *schema.Resource { @@ -13,38 +13,38 @@ func resourceContentfulLocale() *schema.Resource { Delete: resourceDeleteLocale, Schema: map[string]*schema.Schema{ - "version": &schema.Schema{ + "version": { Type: schema.TypeInt, Computed: true, }, - "space_id": &schema.Schema{ + "space_id": { Type: schema.TypeString, Required: true, }, - "name": &schema.Schema{ + "name": { Type: schema.TypeString, Required: true, }, - "code": &schema.Schema{ + "code": { Type: schema.TypeString, Required: true, }, - "fallback_code": &schema.Schema{ + "fallback_code": { Type: schema.TypeString, Optional: true, Default: "en-US", }, - "optional": &schema.Schema{ + "optional": { Type: schema.TypeBool, Optional: true, Default: false, }, - "cda": &schema.Schema{ + "cda": { Type: schema.TypeBool, Optional: true, Default: true, }, - "cma": &schema.Schema{ + "cma": { Type: schema.TypeBool, Optional: true, Default: false, @@ -54,7 +54,7 @@ func resourceContentfulLocale() *schema.Resource { } func resourceCreateLocale(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Contentful) + client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) locale := &contentful.Locale{ @@ -82,7 +82,7 @@ func resourceCreateLocale(d *schema.ResourceData, m interface{}) (err error) { } func resourceReadLocale(d *schema.ResourceData, m interface{}) error { - client := m.(*contentful.Contentful) + client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) localeID := d.Id() @@ -100,7 +100,7 @@ func resourceReadLocale(d *schema.ResourceData, m interface{}) error { } func resourceUpdateLocale(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Contentful) + client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) localeID := d.Id() @@ -130,7 +130,7 @@ func resourceUpdateLocale(d *schema.ResourceData, m interface{}) (err error) { } func resourceDeleteLocale(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Contentful) + client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) localeID := d.Id() diff --git a/resource_contentful_locale_test.go b/resource_contentful_locale_test.go index f6e06aa..b431fe7 100644 --- a/resource_contentful_locale_test.go +++ b/resource_contentful_locale_test.go @@ -7,7 +7,7 @@ import ( "github.com/hashicorp/terraform/helper/acctest" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" - contentful "github.com/tolgaakyuz/contentful-go" + contentful "github.com/labd/contentful-go" ) func TestAccContentfulLocales_Basic(t *testing.T) { @@ -21,7 +21,7 @@ func TestAccContentfulLocales_Basic(t *testing.T) { Providers: testAccProviders, CheckDestroy: testAccContentfulLocaleDestroy, Steps: []resource.TestStep{ - resource.TestStep{ + { Config: testAccContentfulLocaleConfig(spaceName, name), Check: resource.ComposeTestCheckFunc( testAccCheckContentfulLocaleExists("contentful_locale.mylocale", &locale), @@ -35,7 +35,7 @@ func TestAccContentfulLocales_Basic(t *testing.T) { }), ), }, - resource.TestStep{ + { Config: testAccContentfulLocaleUpdateConfig(spaceName, name), Check: resource.ComposeTestCheckFunc( testAccCheckContentfulLocaleExists("contentful_locale.mylocale", &locale), @@ -57,20 +57,20 @@ func testAccCheckContentfulLocaleExists(n string, locale *contentful.Locale) res return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] if !ok { - return fmt.Errorf("Not Found: %s", n) + return fmt.Errorf("not Found: %s", n) } spaceID := rs.Primary.Attributes["space_id"] if spaceID == "" { - return fmt.Errorf("No space_id is set") + return fmt.Errorf("no space_id is set") } localeID := rs.Primary.ID if localeID == "" { - return fmt.Errorf("No locale ID is set") + return fmt.Errorf("no locale ID is set") } - client := testAccProvider.Meta().(*contentful.Contentful) + client := testAccProvider.Meta().(*contentful.Client) contentfulLocale, err := client.Locales.Get(spaceID, localeID) if err != nil { @@ -87,32 +87,32 @@ func testAccCheckContentfulLocaleAttributes(locale *contentful.Locale, attrs map return func(s *terraform.State) error { name := attrs["name"].(string) if locale.Name != name { - return fmt.Errorf("Locale name does not match: %s, %s", locale.Name, name) + return fmt.Errorf("locale name does not match: %s, %s", locale.Name, name) } code := attrs["code"].(string) if locale.Code != code { - return fmt.Errorf("Locale code does not match: %s, %s", locale.Code, code) + return fmt.Errorf("locale code does not match: %s, %s", locale.Code, code) } fallbackCode := attrs["fallback_code"].(string) if locale.FallbackCode != fallbackCode { - return fmt.Errorf("Locale fallback code does not match: %s, %s", locale.FallbackCode, fallbackCode) + return fmt.Errorf("locale fallback code does not match: %s, %s", locale.FallbackCode, fallbackCode) } isOptional := attrs["optional"].(bool) if locale.Optional != isOptional { - return fmt.Errorf("Locale options value does not match: %t, %t", locale.Optional, isOptional) + return fmt.Errorf("locale options value does not match: %t, %t", locale.Optional, isOptional) } isCDA := attrs["cda"].(bool) if locale.CDA != isCDA { - return fmt.Errorf("Locale cda does not match: %t, %t", locale.CDA, isCDA) + return fmt.Errorf("locale cda does not match: %t, %t", locale.CDA, isCDA) } isCMA := attrs["cma"].(bool) if locale.CMA != isCMA { - return fmt.Errorf("Locale cma does not match: %t, %t", locale.CMA, isCMA) + return fmt.Errorf("locale cma does not match: %t, %t", locale.CMA, isCMA) } return nil @@ -127,22 +127,22 @@ func testAccContentfulLocaleDestroy(s *terraform.State) error { spaceID := rs.Primary.Attributes["space_id"] if spaceID == "" { - return fmt.Errorf("No space_id is set") + return fmt.Errorf("no space_id is set") } localeID := rs.Primary.ID if localeID == "" { - return fmt.Errorf("No locale ID is set") + return fmt.Errorf("no locale ID is set") } - client := testAccProvider.Meta().(*contentful.Contentful) + client := testAccProvider.Meta().(*contentful.Client) _, err := client.Locales.Get(spaceID, localeID) if _, ok := err.(contentful.NotFoundError); ok { return nil } - return fmt.Errorf("Locale still exists with id: %s", localeID) + return fmt.Errorf("locale still exists with id: %s", localeID) } return nil diff --git a/resource_contentful_space.go b/resource_contentful_space.go index ee1d4e1..0f7288c 100644 --- a/resource_contentful_space.go +++ b/resource_contentful_space.go @@ -2,7 +2,7 @@ package main import ( "github.com/hashicorp/terraform/helper/schema" - contentful "github.com/tolgaakyuz/contentful-go" + contentful "github.com/labd/contentful-go" ) func resourceContentfulSpace() *schema.Resource { @@ -13,16 +13,16 @@ func resourceContentfulSpace() *schema.Resource { Delete: resourceSpaceDelete, Schema: map[string]*schema.Schema{ - "version": &schema.Schema{ + "version": { Type: schema.TypeInt, Computed: true, }, - "name": &schema.Schema{ + "name": { Type: schema.TypeString, Required: true, }, // Space specific props - "default_locale": &schema.Schema{ + "default_locale": { Type: schema.TypeString, Optional: true, Default: "en", @@ -32,7 +32,7 @@ func resourceContentfulSpace() *schema.Resource { } func resourceSpaceCreate(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Contentful) + client := m.(*contentful.Client) space := &contentful.Space{ Name: d.Get("name").(string), @@ -55,7 +55,7 @@ func resourceSpaceCreate(d *schema.ResourceData, m interface{}) (err error) { } func resourceSpaceRead(d *schema.ResourceData, m interface{}) error { - client := m.(*contentful.Contentful) + client := m.(*contentful.Client) spaceID := d.Id() _, err := client.Spaces.Get(spaceID) @@ -68,7 +68,7 @@ func resourceSpaceRead(d *schema.ResourceData, m interface{}) error { } func resourceSpaceUpdate(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Contentful) + client := m.(*contentful.Client) spaceID := d.Id() space, err := client.Spaces.Get(spaceID) @@ -87,7 +87,7 @@ func resourceSpaceUpdate(d *schema.ResourceData, m interface{}) (err error) { } func resourceSpaceDelete(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Contentful) + client := m.(*contentful.Client) spaceID := d.Id() space, err := client.Spaces.Get(spaceID) diff --git a/resource_contentful_space_test.go b/resource_contentful_space_test.go index da1e9e5..df2bdba 100644 --- a/resource_contentful_space_test.go +++ b/resource_contentful_space_test.go @@ -6,7 +6,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" - contentful "github.com/tolgaakyuz/contentful-go" + contentful "github.com/labd/contentful-go" ) func TestAccContentfulSpace_Basic(t *testing.T) { @@ -16,12 +16,12 @@ func TestAccContentfulSpace_Basic(t *testing.T) { Providers: testAccProviders, CheckDestroy: testAccCheckContentfulSpaceDestroy, Steps: []resource.TestStep{ - resource.TestStep{ + { Config: testAccContentfulSpaceConfig, Check: resource.TestCheckResourceAttr( "contentful_space.myspace", "name", "TF Acc Test Space"), }, - resource.TestStep{ + { Config: testAccContentfulSpaceUpdateConfig, Check: resource.TestCheckResourceAttr( "contentful_space.myspace", "name", "TF Acc Test Changed Space"), @@ -31,7 +31,7 @@ func TestAccContentfulSpace_Basic(t *testing.T) { } func testAccCheckContentfulSpaceDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*contentful.Contentful) + client := testAccProvider.Meta().(*contentful.Client) for _, rs := range s.RootModule().Resources { if rs.Type != "contentful_space" { @@ -40,7 +40,7 @@ func testAccCheckContentfulSpaceDestroy(s *terraform.State) error { space, err := client.Spaces.Get(rs.Primary.ID) if err == nil { - return fmt.Errorf("Space %s still exists after destroy", space.Sys.ID) + return fmt.Errorf("space %s still exists after destroy", space.Sys.ID) } } diff --git a/resource_contentful_webhook.go b/resource_contentful_webhook.go index e7830bd..60f338a 100644 --- a/resource_contentful_webhook.go +++ b/resource_contentful_webhook.go @@ -2,7 +2,7 @@ package main import ( "github.com/hashicorp/terraform/helper/schema" - contentful "github.com/tolgaakyuz/contentful-go" + contentful "github.com/labd/contentful-go" ) func resourceContentfulWebhook() *schema.Resource { @@ -13,38 +13,38 @@ func resourceContentfulWebhook() *schema.Resource { Delete: resourceDeleteWebhook, Schema: map[string]*schema.Schema{ - "version": &schema.Schema{ + "version": { Type: schema.TypeInt, Computed: true, }, - "space_id": &schema.Schema{ + "space_id": { Type: schema.TypeString, Required: true, }, - "name": &schema.Schema{ + "name": { Type: schema.TypeString, Required: true, }, // Webhook specific props - "url": &schema.Schema{ + "url": { Type: schema.TypeString, Required: true, }, - "http_basic_auth_username": &schema.Schema{ + "http_basic_auth_username": { Type: schema.TypeString, Optional: true, Default: "", }, - "http_basic_auth_password": &schema.Schema{ + "http_basic_auth_password": { Type: schema.TypeString, Optional: true, Default: "", }, - "headers": &schema.Schema{ + "headers": { Type: schema.TypeMap, Optional: true, }, - "topics": &schema.Schema{ + "topics": { Type: schema.TypeList, Elem: &schema.Schema{ Type: schema.TypeString, @@ -57,7 +57,7 @@ func resourceContentfulWebhook() *schema.Resource { } func resourceCreateWebhook(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Contentful) + client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) webhook := &contentful.Webhook{ @@ -85,7 +85,7 @@ func resourceCreateWebhook(d *schema.ResourceData, m interface{}) (err error) { } func resourceUpdateWebhook(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Contentful) + client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) webhookID := d.Id() @@ -117,7 +117,7 @@ func resourceUpdateWebhook(d *schema.ResourceData, m interface{}) (err error) { } func resourceReadWebhook(d *schema.ResourceData, m interface{}) error { - client := m.(*contentful.Contentful) + client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) webhookID := d.Id() @@ -135,7 +135,7 @@ func resourceReadWebhook(d *schema.ResourceData, m interface{}) error { } func resourceDeleteWebhook(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Contentful) + client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) webhookID := d.Id() @@ -197,7 +197,7 @@ func setWebhookProperties(d *schema.ResourceData, webhook *contentful.Webhook) ( } func transformHeadersToContentfulFormat(headersTerraform interface{}) []*contentful.WebhookHeader { - headers := []*contentful.WebhookHeader{} + var headers []*contentful.WebhookHeader for k, v := range headersTerraform.(map[string]interface{}) { headers = append(headers, &contentful.WebhookHeader{ diff --git a/resource_contentful_webhook_test.go b/resource_contentful_webhook_test.go index c35e59f..a4a6bb3 100644 --- a/resource_contentful_webhook_test.go +++ b/resource_contentful_webhook_test.go @@ -6,7 +6,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" - contentful "github.com/tolgaakyuz/contentful-go" + contentful "github.com/labd/contentful-go" ) func TestAccContentfulWebhook_Basic(t *testing.T) { @@ -17,24 +17,24 @@ func TestAccContentfulWebhook_Basic(t *testing.T) { Providers: testAccProviders, CheckDestroy: testAccContentfulWebhookDestroy, Steps: []resource.TestStep{ - resource.TestStep{ + { Config: testAccContentfulWebhookConfig, Check: resource.ComposeTestCheckFunc( testAccCheckContentfulWebhookExists("contentful_webhook.mywebhook", &webhook), testAccCheckContentfulWebhookAttributes(&webhook, map[string]interface{}{ - "name": "webhook-name", - "url": "https://www.example.com/test", + "name": "webhook-name", + "url": "https://www.example.com/test", "http_basic_auth_username": "username", }), ), }, - resource.TestStep{ + { Config: testAccContentfulWebhookUpdateConfig, Check: resource.ComposeTestCheckFunc( testAccCheckContentfulWebhookExists("contentful_webhook.mywebhook", &webhook), testAccCheckContentfulWebhookAttributes(&webhook, map[string]interface{}{ - "name": "webhook-name-updated", - "url": "https://www.example.com/test-updated", + "name": "webhook-name-updated", + "url": "https://www.example.com/test-updated", "http_basic_auth_username": "username-updated", }), ), @@ -47,21 +47,21 @@ func testAccCheckContentfulWebhookExists(n string, webhook *contentful.Webhook) return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] if !ok { - return fmt.Errorf("Not Found: %s", n) + return fmt.Errorf("not Found: %s", n) } // get space id from resource data spaceID := rs.Primary.Attributes["space_id"] if spaceID == "" { - return fmt.Errorf("No space_id is set") + return fmt.Errorf("no space_id is set") } // check webhook resource id if rs.Primary.ID == "" { - return fmt.Errorf("No webhook ID is set") + return fmt.Errorf("no webhook ID is set") } - client := testAccProvider.Meta().(*contentful.Contentful) + client := testAccProvider.Meta().(*contentful.Client) contentfulWebhook, err := client.Webhooks.Get(spaceID, rs.Primary.ID) if err != nil { @@ -78,12 +78,12 @@ func testAccCheckContentfulWebhookAttributes(webhook *contentful.Webhook, attrs return func(s *terraform.State) error { name := attrs["name"].(string) if webhook.Name != name { - return fmt.Errorf("Webhook name does not match: %s, %s", webhook.Name, name) + return fmt.Errorf("webhook name does not match: %s, %s", webhook.Name, name) } url := attrs["url"].(string) if webhook.URL != url { - return fmt.Errorf("Webhook url does not match: %s, %s", webhook.URL, url) + return fmt.Errorf("webhook url does not match: %s, %s", webhook.URL, url) } /* topics := attrs["topics"].([]string) @@ -92,7 +92,7 @@ func testAccCheckContentfulWebhookAttributes(webhook *contentful.Webhook, attrs httpBasicAuthUsername := attrs["http_basic_auth_username"].(string) if webhook.HTTPBasicUsername != httpBasicAuthUsername { - return fmt.Errorf("Webhook http_basic_auth_username does not match: %s, %s", webhook.HTTPBasicUsername, httpBasicAuthUsername) + return fmt.Errorf("webhook http_basic_auth_username does not match: %s, %s", webhook.HTTPBasicUsername, httpBasicAuthUsername) } return nil @@ -108,23 +108,23 @@ func testAccContentfulWebhookDestroy(s *terraform.State) error { // get space id from resource data spaceID := rs.Primary.Attributes["space_id"] if spaceID == "" { - return fmt.Errorf("No space_id is set") + return fmt.Errorf("no space_id is set") } // check webhook resource id if rs.Primary.ID == "" { - return fmt.Errorf("No webhook ID is set") + return fmt.Errorf("no webhook ID is set") } // sdk client - client := testAccProvider.Meta().(*contentful.Contentful) + client := testAccProvider.Meta().(*contentful.Client) _, err := client.Webhooks.Get(spaceID, rs.Primary.ID) if _, ok := err.(contentful.NotFoundError); ok { return nil } - return fmt.Errorf("Webhook still exists with id: %s", rs.Primary.ID) + return fmt.Errorf("webhook still exists with id: %s", rs.Primary.ID) } return nil From 42b9af3b7d8dd151a649bba7dfdea8903b3caf02 Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Wed, 15 Apr 2020 17:05:16 +0200 Subject: [PATCH 095/192] Fixed non working code and some test related bugs. The unit tests no longer create a space themselves. This because most Contentful users do not have the rights to create spaces in their organization, so automatically creating a space would result in a FAIL. --- resource_contentful_apikey.go | 8 + resource_contentful_apikey_test.go | 41 +-- resource_contentful_contenttype.go | 447 ++++++++++++++++++++++-- resource_contentful_contenttype_test.go | 125 +++---- resource_contentful_locale_test.go | 42 +-- resource_contentful_space_test.go | 1 - 6 files changed, 520 insertions(+), 144 deletions(-) diff --git a/resource_contentful_apikey.go b/resource_contentful_apikey.go index 7d3b787..2de94d7 100644 --- a/resource_contentful_apikey.go +++ b/resource_contentful_apikey.go @@ -17,6 +17,10 @@ func resourceContentfulAPIKey() *schema.Resource { Type: schema.TypeInt, Computed: true, }, + "access_token": { + Type: schema.TypeString, + Computed: true, + }, "space_id": { Type: schema.TypeString, Required: true, @@ -126,5 +130,9 @@ func setAPIKeyProperties(d *schema.ResourceData, apiKey *contentful.APIKey) erro return err } + if err := d.Set("access_token", apiKey.AccessToken); err != nil { + return err + } + return nil } diff --git a/resource_contentful_apikey_test.go b/resource_contentful_apikey_test.go index 5531c69..2b76185 100644 --- a/resource_contentful_apikey_test.go +++ b/resource_contentful_apikey_test.go @@ -13,7 +13,6 @@ import ( func TestAccContentfulAPIKey_Basic(t *testing.T) { var apiKey contentful.APIKey - spaceName := fmt.Sprintf("space-name-%s", acctest.RandString(3)) name := fmt.Sprintf("apikey-name-%s", acctest.RandString(3)) description := fmt.Sprintf("apikey-description-%s", acctest.RandString(3)) @@ -22,8 +21,8 @@ func TestAccContentfulAPIKey_Basic(t *testing.T) { Providers: testAccProviders, CheckDestroy: testAccContentfulAPIKeyDestroy, Steps: []resource.TestStep{ - resource.TestStep{ - Config: testAccContentfulAPIKeyConfig(spaceName, name, description), + { + Config: testAccContentfulAPIKeyConfig(name, description), Check: resource.ComposeTestCheckFunc( testAccCheckContentfulAPIKeyExists("contentful_apikey.myapikey", &apiKey), testAccCheckContentfulAPIKeyAttributes(&apiKey, map[string]interface{}{ @@ -32,8 +31,8 @@ func TestAccContentfulAPIKey_Basic(t *testing.T) { }), ), }, - resource.TestStep{ - Config: testAccContentfulAPIKeyUpdateConfig(spaceName, name, description), + { + Config: testAccContentfulAPIKeyUpdateConfig(name, description), Check: resource.ComposeTestCheckFunc( testAccCheckContentfulAPIKeyExists("contentful_apikey.myapikey", &apiKey), testAccCheckContentfulAPIKeyAttributes(&apiKey, map[string]interface{}{ @@ -50,17 +49,17 @@ func testAccCheckContentfulAPIKeyExists(n string, apiKey *contentful.APIKey) res return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] if !ok { - return fmt.Errorf("Not Found: %s", n) + return fmt.Errorf("not Found: %s", n) } spaceID := rs.Primary.Attributes["space_id"] if spaceID == "" { - return fmt.Errorf("No space_id is set") + return fmt.Errorf("no space_id is set") } apiKeyID := rs.Primary.ID if apiKeyID == "" { - return fmt.Errorf("No api key ID is set") + return fmt.Errorf("no api key ID is set") } client := testAccProvider.Meta().(*contentful.Client) @@ -101,12 +100,12 @@ func testAccContentfulAPIKeyDestroy(s *terraform.State) error { // get space id from resource data spaceID := rs.Primary.Attributes["space_id"] if spaceID == "" { - return fmt.Errorf("No space_id is set") + return fmt.Errorf("no space_id is set") } apiKeyID := rs.Primary.ID if apiKeyID == "" { - return fmt.Errorf("No apikey ID is set") + return fmt.Errorf("no apikey ID is set") } client := testAccProvider.Meta().(*contentful.Client) @@ -116,38 +115,30 @@ func testAccContentfulAPIKeyDestroy(s *terraform.State) error { return nil } - return fmt.Errorf("Api Key still exists with id: %s", rs.Primary.ID) + return fmt.Errorf("api Key still exists with id: %s", rs.Primary.ID) } return nil } -func testAccContentfulAPIKeyConfig(spaceName, name, description string) string { +func testAccContentfulAPIKeyConfig(name, description string) string { return fmt.Sprintf(` -resource "contentful_space" "myspace" { - name = "%s" -} - resource "contentful_apikey" "myapikey" { - space_id = "${contentful_space.myspace.id}" + space_id = "uhwvl4veejyj" name = "%s" description = "%s" } -`, spaceName, name, description) +`, name, description) } -func testAccContentfulAPIKeyUpdateConfig(spaceName, name, description string) string { +func testAccContentfulAPIKeyUpdateConfig(name, description string) string { return fmt.Sprintf(` -resource "contentful_space" "myspace" { - name = "%s" -} - resource "contentful_apikey" "myapikey" { - space_id = "${contentful_space.myspace.id}" + space_id = "uhwvl4veejyj" name = "%s-updated" description = "%s-updated" } -`, spaceName, name, description) +`, name, description) } diff --git a/resource_contentful_contenttype.go b/resource_contentful_contenttype.go index b261ba7..116932e 100644 --- a/resource_contentful_contenttype.go +++ b/resource_contentful_contenttype.go @@ -3,6 +3,7 @@ package main import ( "github.com/hashicorp/terraform/helper/schema" contentful "github.com/labd/contentful-go" + "time" ) func resourceContentfulContentType() *schema.Resource { @@ -35,9 +36,8 @@ func resourceContentfulContentType() *schema.Resource { Required: true, }, "field": { - Type: schema.TypeSet, + Type: schema.TypeList, Required: true, - MinItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "id": { @@ -48,7 +48,6 @@ func resourceContentfulContentType() *schema.Resource { Type: schema.TypeString, Required: true, }, - //@TODO Add ValidateFunc to validate field type "type": { Type: schema.TypeString, Required: true, @@ -58,7 +57,7 @@ func resourceContentfulContentType() *schema.Resource { Optional: true, }, "items": { - Type: schema.TypeSet, + Type: schema.TypeList, Optional: true, MaxItems: 1, Elem: &schema.Resource{ @@ -67,15 +66,15 @@ func resourceContentfulContentType() *schema.Resource { Type: schema.TypeString, Required: true, }, - "validations": { - Type: schema.TypeList, - Optional: true, - Elem: &schema.Schema{Type: schema.TypeString}, - }, "link_type": { Type: schema.TypeString, Required: true, }, + "validation": { + Type: schema.TypeList, + Optional: true, + Elem: generateValidationSchema(), + }, }, }, }, @@ -99,10 +98,10 @@ func resourceContentfulContentType() *schema.Resource { Optional: true, Default: false, }, - "validations": { + "validation": { Type: schema.TypeList, Optional: true, - Elem: &schema.Schema{Type: schema.TypeString}, + Elem: generateValidationSchema(), }, }, }, @@ -125,8 +124,9 @@ func resourceContentTypeCreate(d *schema.ResourceData, m interface{}) (err error ct.Description = description.(string) } - for _, rawField := range d.Get("field").(*schema.Set).List() { - field := rawField.(map[string]interface{}) + rawField := d.Get("field").([]interface{}) + for i := 0; i < len(rawField); i++ { + field := rawField[i].(map[string]interface{}) contentfulField := &contentful.Field{ ID: field["id"].(string), @@ -151,7 +151,7 @@ func resourceContentTypeCreate(d *schema.ResourceData, m interface{}) (err error contentfulField.Validations = parsedValidations } - if items := processItems(field["items"].(*schema.Set)); items != nil { + if items := processItems(field["items"].([]interface{})); items != nil { contentfulField.Items = items } @@ -163,7 +163,6 @@ func resourceContentTypeCreate(d *schema.ResourceData, m interface{}) (err error } if err = client.ContentTypes.Activate(spaceID, ct); err != nil { - //@TODO Maybe delete the CT ? return err } @@ -207,7 +206,7 @@ func resourceContentTypeUpdate(d *schema.ResourceData, m interface{}) (err error if d.HasChange("field") { old, nw := d.GetChange("field") - existingFields, deletedFields = checkFieldChanges(old.(*schema.Set), nw.(*schema.Set)) + existingFields, deletedFields = checkFieldChanges(old.([]interface{}), nw.([]interface{})) ct.Fields = existingFields @@ -224,7 +223,6 @@ func resourceContentTypeUpdate(d *schema.ResourceData, m interface{}) (err error } if err = client.ContentTypes.Activate(spaceID, ct); err != nil { - //@TODO Maybe delete the CT ? return err } @@ -236,7 +234,6 @@ func resourceContentTypeUpdate(d *schema.ResourceData, m interface{}) (err error } if err = client.ContentTypes.Activate(spaceID, ct); err != nil { - //@TODO Maybe delete the CT ? return err } } @@ -274,18 +271,18 @@ func setContentTypeProperties(d *schema.ResourceData, ct *contentful.ContentType return nil } -func checkFieldChanges(old, new *schema.Set) ([]*contentful.Field, []*contentful.Field) { +func checkFieldChanges(old, new []interface{}) ([]*contentful.Field, []*contentful.Field) { var contentfulField *contentful.Field var existingFields []*contentful.Field var deletedFields []*contentful.Field var fieldRemoved bool - for _, f := range old.List() { - oldField := f.(map[string]interface{}) + for i := 0; i < len(old); i++ { + oldField := old[i].(map[string]interface{}) fieldRemoved = true - for _, newField := range new.List() { - if oldField["id"].(string) == newField.(map[string]interface{})["id"].(string) { + for j := 0; j < len(new); j++ { + if oldField["id"].(string) == new[j].(map[string]interface{})["id"].(string) { fieldRemoved = false break } @@ -306,8 +303,8 @@ func checkFieldChanges(old, new *schema.Set) ([]*contentful.Field, []*contentful } } - for _, f := range new.List() { - newField := f.(map[string]interface{}) + for k := 0; k < len(new); k++ { + newField := new[k].(map[string]interface{}) contentfulField = &contentful.Field{ ID: newField["id"].(string), @@ -329,7 +326,7 @@ func checkFieldChanges(old, new *schema.Set) ([]*contentful.Field, []*contentful contentfulField.Validations = parsedValidations } - if items := processItems(newField["items"].(*schema.Set)); items != nil { + if items := processItems(newField["items"].([]interface{})); items != nil { contentfulField.Items = items } @@ -339,11 +336,11 @@ func checkFieldChanges(old, new *schema.Set) ([]*contentful.Field, []*contentful return existingFields, deletedFields } -func processItems(fieldItems *schema.Set) *contentful.FieldTypeArrayItem { +func processItems(fieldItems []interface{}) *contentful.FieldTypeArrayItem { var items *contentful.FieldTypeArrayItem - for _, i := range fieldItems.List() { - item := i.(map[string]interface{}) + for i := 0; i < len(fieldItems); i++ { + item := fieldItems[i].(map[string]interface{}) var validations []contentful.FieldValidation @@ -359,3 +356,395 @@ func processItems(fieldItems *schema.Set) *contentful.FieldTypeArrayItem { } return items } + +// Expanders +// noinspection GoUnusedFunction +func expandContentTypeField(in interface{}) *contentful.Field { + field := &contentful.Field{} + m := in.(map[string]interface{}) + if v, ok := m["id"].(string); ok { + field.ID = v + } + if v, ok := m["name"].(string); ok { + field.Name = v + } + if v, ok := m["type"].(string); ok { + field.Type = v + } + if v, ok := m["link_type"].(string); ok { + field.LinkType = v + } + if v, ok := m["required"].(bool); ok { + field.Required = v + } + if v, ok := m["localized"].(bool); ok { + field.Localized = v + } + if v, ok := m["disabled"].(bool); ok { + field.Disabled = v + } + if v, ok := m["omitted"].(bool); ok { + field.Omitted = v + } + if v, ok := m["validation"].([]interface{}); ok && len(v) > 0 { + validations := make([]contentful.FieldValidation, len(v)) + for i, val := range v { + validations[i] = expandContentTypeFieldValidation(val) + } + field.Validations = validations + } + return field +} + +func expandContentTypeFieldValidation(in interface{}) contentful.FieldValidation { + m := in.(map[string]interface{}) + if v, ok := m["link"].([]string); ok { + return contentful.FieldValidationLink{ + LinkContentType: v, + } + } + if v, ok := m["mime_type"].([]string); ok { + return contentful.FieldValidationMimeType{ + MimeTypes: v, + } + } + if v, ok := m["dimension"].([]interface{}); ok { + return expandContentTypeFieldValidationDimension(v) + } + if v, ok := m["size"].([]interface{}); ok { + return expandContentTypeFieldValidationSize(v) + } + if v, ok := m["file_size"].([]interface{}); ok { + return expandContentTypeFieldValidationFileSize(v) + } + if v, ok := m["unique"].(bool); ok { + return contentful.FieldValidationUnique{ + Unique: v, + } + } + if v, ok := m["range"].([]interface{}); ok { + return expandContentTypeFieldValidationRange(v) + } + if v, ok := m["date"].([]interface{}); ok { + return expandContentTypeFieldValidationDate(v) + } + return nil +} + +func expandContentTypeFieldValidationDimension(in []interface{}) contentful.FieldValidation { + if len(in) == 0 || in[0] == nil { + return contentful.FieldValidationDimension{} + } + + validation := contentful.FieldValidationDimension{} + m := in[0].(map[string]interface{}) + if v, ok := m["min_width"].(float64); ok { + if validation.Width == nil { + validation.Width = &contentful.MinMax{} + } + validation.Width.Min = v + } + if v, ok := m["max_width"].(float64); ok { + if validation.Width == nil { + validation.Width = &contentful.MinMax{} + } + validation.Width.Max = v + } + if v, ok := m["min_height"].(float64); ok { + if validation.Height == nil { + validation.Width = &contentful.MinMax{} + } + validation.Height.Min = v + } + if v, ok := m["max_height"].(float64); ok { + if validation.Height == nil { + validation.Width = &contentful.MinMax{} + } + validation.Height.Max = v + } + if v, ok := m["err_message"].(string); ok { + validation.ErrorMessage = v + } + return validation +} + +func expandContentTypeFieldValidationSize(in []interface{}) contentful.FieldValidation { + if len(in) == 0 || in[0] == nil { + return contentful.FieldValidationSize{} + } + + validation := contentful.FieldValidationSize{} + m := in[0].(map[string]interface{}) + if v, ok := m["min"].(float64); ok { + if validation.Size == nil { + validation.Size = &contentful.MinMax{} + } + validation.Size.Min = v + } + if v, ok := m["max"].(float64); ok { + if validation.Size == nil { + validation.Size = &contentful.MinMax{} + } + validation.Size.Max = v + } + if v, ok := m["err_message"].(string); ok { + validation.ErrorMessage = v + } + return validation +} + +func expandContentTypeFieldValidationFileSize(in []interface{}) contentful.FieldValidation { + if len(in) == 0 || in[0] == nil { + return contentful.FieldValidationFileSize{} + } + + validation := contentful.FieldValidationFileSize{} + m := in[0].(map[string]interface{}) + if v, ok := m["min"].(float64); ok { + if validation.Size == nil { + validation.Size = &contentful.MinMax{} + } + validation.Size.Min = v + } + if v, ok := m["max"].(float64); ok { + if validation.Size == nil { + validation.Size = &contentful.MinMax{} + } + validation.Size.Max = v + } + if v, ok := m["err_message"].(string); ok { + validation.ErrorMessage = v + } + return validation +} + +func expandContentTypeFieldValidationRange(in []interface{}) contentful.FieldValidation { + if len(in) == 0 || in[0] == nil { + return contentful.FieldValidationRange{} + } + + validation := contentful.FieldValidationRange{} + m := in[0].(map[string]interface{}) + if v, ok := m["min"].(float64); ok { + if validation.Range == nil { + validation.Range = &contentful.MinMax{} + } + validation.Range.Min = v + } + if v, ok := m["max"].(float64); ok { + if validation.Range == nil { + validation.Range = &contentful.MinMax{} + } + validation.Range.Max = v + } + if v, ok := m["err_message"].(string); ok { + validation.ErrorMessage = v + } + return validation +} + +func expandContentTypeFieldValidationDate(in []interface{}) contentful.FieldValidation { + if len(in) == 0 || in[0] == nil { + return contentful.FieldValidationDate{} + } + + validation := contentful.FieldValidationDate{} + m := in[0].(map[string]interface{}) + if v, ok := m["min"].(time.Time); ok { + if validation.Range == nil { + validation.Range = &contentful.DateMinMax{} + } + validation.Range.Min = v + } + if v, ok := m["max"].(time.Time); ok { + if validation.Range == nil { + validation.Range = &contentful.DateMinMax{} + } + validation.Range.Max = v + } + if v, ok := m["err_message"].(string); ok { + validation.ErrorMessage = v + } + return validation +} + +// noinspection GoUnusedFunction +func expandContentTypeFieldValidationRegex(in []interface{}) contentful.FieldValidation { + if len(in) == 0 || in[0] == nil { + return contentful.FieldValidationRegex{} + } + + validation := contentful.FieldValidationRegex{} + m := in[0].(map[string]interface{}) + if v, ok := m["pattern"].(string); ok { + if validation.Regex == nil { + validation.Regex = &contentful.Regex{} + } + validation.Regex.Pattern = v + } + if v, ok := m["flags"].(string); ok { + if validation.Regex == nil { + validation.Regex = &contentful.Regex{} + } + validation.Regex.Flags = v + } + if v, ok := m["err_message"].(string); ok { + validation.ErrorMessage = v + } + return validation +} + +func generateValidationSchema() *schema.Resource { + return &schema.Resource{ + Schema: map[string]*schema.Schema{ + "link": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "mime_type": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "dimension": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "min_width": { + Type: schema.TypeFloat, + Required: true, + }, + "max_width": { + Type: schema.TypeFloat, + Required: true, + }, + "min_height": { + Type: schema.TypeFloat, + Required: true, + }, + "max_height": { + Type: schema.TypeFloat, + Required: true, + }, + "err_message": { + Type: schema.TypeString, + Required: true, + }, + }, + }, + }, + "size": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "min": { + Type: schema.TypeFloat, + Optional: true, + }, + "max": { + Type: schema.TypeFloat, + Optional: true, + }, + "err_message": { + Type: schema.TypeString, + Optional: true, + }, + }, + }, + }, + "file_size": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "min": { + Type: schema.TypeFloat, + Optional: true, + }, + "max": { + Type: schema.TypeFloat, + Optional: true, + }, + "err_message": { + Type: schema.TypeString, + Optional: true, + }, + }, + }, + }, + "unique": { + Type: schema.TypeBool, + Optional: true, + }, + "range": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "min": { + Type: schema.TypeFloat, + Optional: true, + }, + "max": { + Type: schema.TypeFloat, + Optional: true, + }, + "err_message": { + Type: schema.TypeString, + Optional: true, + }, + }, + }, + }, + "date": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "min": { + Type: schema.TypeString, + Optional: true, + }, + "max": { + Type: schema.TypeString, + Optional: true, + }, + "err_message": { + Type: schema.TypeString, + Optional: true, + }, + }, + }, + }, + "regex": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "pattern": { + Type: schema.TypeString, + Optional: true, + }, + "flags": { + Type: schema.TypeString, + Optional: true, + }, + "err_message": { + Type: schema.TypeString, + Optional: true, + }, + }, + }, + }, + }, + } +} diff --git a/resource_contentful_contenttype_test.go b/resource_contentful_contenttype_test.go index 5900087..fa1afdb 100644 --- a/resource_contentful_contenttype_test.go +++ b/resource_contentful_contenttype_test.go @@ -34,6 +34,7 @@ func TestAccContentfulContentType_Basic(t *testing.T) { }) } +// noinspection GoUnusedFunction func testAccCheckContentfulContentTypeExists(n string, contentType *contentful.ContentType) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] @@ -81,113 +82,119 @@ func testAccCheckContentfulContentTypeDestroy(s *terraform.State) (err error) { return nil } - return fmt.Errorf("content Type still exists with id: %s", rs.Primary.ID) + return fmt.Errorf("content type still exists with id: %s", rs.Primary.ID) } return nil } var testAccContentfulContentTypeConfig = ` -// resource "contentful_space" "myspace" { -// name = "TF Acc Test Space" -// } - resource "contentful_contenttype" "mycontenttype" { - space_id = "${contentful_space.myspace.id}" - + space_id = "uhwvl4veejyj" name = "TF Acc Test CT 1" description = "Terraform Acc Test Content Type" display_field = "field1" - field { - id = "field1" - name = "Field 1" - type = "Text" - required = true + disabled = false + id = "field1" + localized = false + name = "Field 1" + omitted = false + required = true + type = "Text" } - field { - id = "field2" - name = "Field 2" - type = "Integer" - required = false + disabled = false + id = "field2" + localized = false + name = "Field 2" + omitted = false + required = true + type = "Integer" } } ` var testAccContentfulContentTypeUpdateConfig = ` resource "contentful_contenttype" "mycontenttype" { - space_id = "${contentful_space.myspace.id}" - + space_id = "uhwvl4veejyj" name = "TF Acc Test CT name change" description = "Terraform Acc Test Content Type description change" display_field = "field1" - field { - id = "field1" - name = "Field 1 name change" - type = "Text" - required = true + disabled = false + id = "field1" + localized = false + name = "Field 1 name change" + omitted = false + required = true + type = "Text" } - field { - id = "field3" - name = "Field 3 new field" - type = "Integer" - required = true + disabled = false + id = "field3" + localized = false + name = "Field 3 new field" + omitted = false + required = true + type = "Integer" } } ` + var testAccContentfulContentTypeLinkConfig = ` resource "contentful_contenttype" "mycontenttype" { - space_id = "${contentful_space.myspace.id}" - + space_id = "uhwvl4veejyj" name = "TF Acc Test CT name change" description = "Terraform Acc Test Content Type description change" display_field = "field1" - field { - id = "field1" - name = "Field 1 name change" - type = "Text" - required = true + disabled = false + id = "field1" + localized = false + name = "Field 1 name change" + omitted = false + required = true + type = "Text" } - field { - id = "field3" - name = "Field 3 new field" - type = "Integer" - required = true + disabled = false + id = "field3" + localized = false + name = "Field 3 new field" + omitted = false + required = true + type = "Integer" } } resource "contentful_contenttype" "mylinked_contenttype" { - space_id = "${contentful_space.myspace.id}" - - name = "TF Acc Test Linked CT" - description = "Terraform Acc Test Content Type with links" + space_id = "uhwvl4veejyj" + name = "TF Acc Test Linked CT" + description = "Terraform Acc Test Content Type with links" display_field = "asset_field" - field { - id = "asset_field" + id = "asset_field" name = "Asset Field" type = "Array" - items { - type = "Link" - link_type = "Asset" - } + items { + type = "Link" + link_type = "Asset" + } required = true } - field { - id = "entry_link_field" - name = "Entry Link Field" - type = "Link" - link_type = "Entry" - validations = ["{\"linkContentType\": [\"${contentful_contenttype.mycontenttype.id}\"]}"] + id = "entry_link_field" + name = "Entry Link Field" + type = "Link" + link_type = "Entry" + dynamic "validation" { + for_each = ["{\"linkContentType\": [\"${contentful_contenttype.mycontenttype.id}\"]}"] + content { + link = lookup(contentful_contenttype.mycontenttype, "link", null) + } + } required = false } - } - ` diff --git a/resource_contentful_locale_test.go b/resource_contentful_locale_test.go index b431fe7..b4ba1b6 100644 --- a/resource_contentful_locale_test.go +++ b/resource_contentful_locale_test.go @@ -4,7 +4,6 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform/helper/acctest" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" contentful "github.com/labd/contentful-go" @@ -13,20 +12,17 @@ import ( func TestAccContentfulLocales_Basic(t *testing.T) { var locale contentful.Locale - spaceName := fmt.Sprintf("space-name-%s", acctest.RandString(3)) - name := fmt.Sprintf("locale-name-%s", acctest.RandString(3)) - resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, CheckDestroy: testAccContentfulLocaleDestroy, Steps: []resource.TestStep{ { - Config: testAccContentfulLocaleConfig(spaceName, name), + Config: testAccContentfulLocaleConfig, Check: resource.ComposeTestCheckFunc( testAccCheckContentfulLocaleExists("contentful_locale.mylocale", &locale), testAccCheckContentfulLocaleAttributes(&locale, map[string]interface{}{ - "name": name, + "name": "locale-name", "code": "de", "fallback_code": "en-US", "optional": false, @@ -36,11 +32,11 @@ func TestAccContentfulLocales_Basic(t *testing.T) { ), }, { - Config: testAccContentfulLocaleUpdateConfig(spaceName, name), + Config: testAccContentfulLocaleUpdateConfig, Check: resource.ComposeTestCheckFunc( testAccCheckContentfulLocaleExists("contentful_locale.mylocale", &locale), testAccCheckContentfulLocaleAttributes(&locale, map[string]interface{}{ - "name": fmt.Sprintf("%s-updated", name), + "name": "locale-name-updated", "code": "es", "fallback_code": "en-US", "optional": true, @@ -148,42 +144,28 @@ func testAccContentfulLocaleDestroy(s *terraform.State) error { return nil } -func testAccContentfulLocaleConfig(spaceName, name string) string { - return fmt.Sprintf(` -resource "contentful_space" "myspace" { - name = "%s" - default_locale = "en-US" -} - +var testAccContentfulLocaleConfig = ` resource "contentful_locale" "mylocale" { - space_id = "${contentful_space.myspace.id}" + space_id = "uhwvl4veejyj" - name = "%s" + name = "locale-name" code = "de" fallback_code = "en-US" optional = false cda = false cma = true } -`, spaceName, name) -} - -func testAccContentfulLocaleUpdateConfig(spaceName, name string) string { - return fmt.Sprintf(` -resource "contentful_space" "myspace" { - name = "%s" - default_locale = "en-US" -} +` +var testAccContentfulLocaleUpdateConfig = ` resource "contentful_locale" "mylocale" { - space_id = "${contentful_space.myspace.id}" + space_id = "uhwvl4veejyj" - name = "%s-updated" + name = "locale-name-updated" code = "es" fallback_code = "en-US" optional = true cda = true cma = false } -`, spaceName, name) -} +` diff --git a/resource_contentful_space_test.go b/resource_contentful_space_test.go index df2bdba..f52b856 100644 --- a/resource_contentful_space_test.go +++ b/resource_contentful_space_test.go @@ -10,7 +10,6 @@ import ( ) func TestAccContentfulSpace_Basic(t *testing.T) { - t.Skip() resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, From 7ef3977e4afbb2879d4aa1843d8ea43059858eca Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Thu, 16 Apr 2020 10:05:09 +0200 Subject: [PATCH 096/192] Correct project setup Fixed the setup of the project files, and edited the makefile to accept the usual commands. --- .gitignore | 17 ++++++++ Dockerfile-test | 11 ------ Makefile | 39 ++++++------------- circle.yml | 15 ------- constants.go => contentful/constants.go | 2 +- provider.go => contentful/provider.go | 2 +- .../provider_test.go | 2 +- .../resource_contentful_apikey.go | 2 +- .../resource_contentful_apikey_test.go | 2 +- .../resource_contentful_contenttype.go | 2 +- .../resource_contentful_contenttype_test.go | 2 +- .../resource_contentful_locale.go | 2 +- .../resource_contentful_locale_test.go | 2 +- .../resource_contentful_space.go | 2 +- .../resource_contentful_space_test.go | 2 +- .../resource_contentful_webhook.go | 2 +- .../resource_contentful_webhook_test.go | 2 +- install-dependencies.sh | 7 ---- main.go | 3 +- 19 files changed, 44 insertions(+), 74 deletions(-) delete mode 100644 Dockerfile-test delete mode 100644 circle.yml rename constants.go => contentful/constants.go (96%) rename provider.go => contentful/provider.go (98%) rename provider_test.go => contentful/provider_test.go (98%) rename resource_contentful_apikey.go => contentful/resource_contentful_apikey.go (99%) rename resource_contentful_apikey_test.go => contentful/resource_contentful_apikey_test.go (99%) rename resource_contentful_contenttype.go => contentful/resource_contentful_contenttype.go (99%) rename resource_contentful_contenttype_test.go => contentful/resource_contentful_contenttype_test.go (99%) rename resource_contentful_locale.go => contentful/resource_contentful_locale.go (99%) rename resource_contentful_locale_test.go => contentful/resource_contentful_locale_test.go (99%) rename resource_contentful_space.go => contentful/resource_contentful_space.go (99%) rename resource_contentful_space_test.go => contentful/resource_contentful_space_test.go (98%) rename resource_contentful_webhook.go => contentful/resource_contentful_webhook.go (99%) rename resource_contentful_webhook_test.go => contentful/resource_contentful_webhook_test.go (99%) delete mode 100755 install-dependencies.sh diff --git a/.gitignore b/.gitignore index 62b43e7..3c647cf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,19 @@ terraform-provider-contentful .envrc + +*.backup +/dist/* +coverage.txt + +*.tf +.terraform/ +terraform.* +crash.log + +.vscode +.idea + +/local/* +!/local/*.example + +vendor/ \ No newline at end of file diff --git a/Dockerfile-test b/Dockerfile-test deleted file mode 100644 index 72b719c..0000000 --- a/Dockerfile-test +++ /dev/null @@ -1,11 +0,0 @@ -FROM golang:1.9 - -WORKDIR /go/src/github.com/labd/terraform-contentful - -# http://stackoverflow.com/questions/39278756/cache-go-get-in-docker-build -COPY ./install-dependencies.sh /go/src/github.com/labd/terraform-contentful -RUN ./install-dependencies.sh - -COPY . /go/src/github.com/labd/terraform-contentful - -CMD go test -v diff --git a/Makefile b/Makefile index bce3756..c7af448 100644 --- a/Makefile +++ b/Makefile @@ -1,31 +1,16 @@ -.PHONY: build build: - docker build -t contentful-terraform-test -f Dockerfile-test . + go build -o terraform-provider-contentful -.PHONY: test-unit -test-unit: build - docker run \ - contentful-terraform-test \ - go test -v +format: + go fmt ./... -# Runs an end-to-end integration test using Contentful. -# Requires that the following environment variables are set: -# - CONTENTFUL_MANAGEMENT_TOKEN -# - CONTENTFUL_ORGANIZATION_ID -.PHONY: test-integration -test-integration: build - docker run \ - -e CONTENTFUL_MANAGEMENT_TOKEN \ - -e CONTENTFUL_ORGANIZATION_ID \ - -e "TF_ACC=true" \ - contentful-terraform-test \ - go test -v +test: + TF_ACC=1 go test -v -.PHONY: interactive -interactive: - docker run -it \ - -v $(shell pwd):/go/src/github.com/danihodovic/contentful-terraform \ - -e CONTENTFUL_MANAGEMENT_TOKEN \ - -e CONTENTFUL_ORGANIZATION_ID \ - contentful-terraform-test \ - bash +coverage-html: + go test -race -coverprofile=coverage.txt -covermode=atomic -coverpkg=./... ./... + go tool cover -html=coverage.txt + +coverage: + go test -race -coverprofile=coverage.txt -covermode=atomic -coverpkg=./... ./... + go tool cover -func=coverage.txt diff --git a/circle.yml b/circle.yml deleted file mode 100644 index 1959fde..0000000 --- a/circle.yml +++ /dev/null @@ -1,15 +0,0 @@ -machine: - pre: - # Install docker 1.10.0, can be removed when circle ships it - # https://discuss.circleci.com/t/docker-1-10-0-is-available-beta/2100 - - curl -sSL https://s3.amazonaws.com/circle-downloads/install-circleci-docker.sh | bash -s -- 1.10.0 - services: - - docker - -dependencies: - override: - - make build - -test: - override: - - make test-unit diff --git a/constants.go b/contentful/constants.go similarity index 96% rename from constants.go rename to contentful/constants.go index 5ea01bd..3bff800 100644 --- a/constants.go +++ b/contentful/constants.go @@ -1,4 +1,4 @@ -package main +package contentful import ( "errors" diff --git a/provider.go b/contentful/provider.go similarity index 98% rename from provider.go rename to contentful/provider.go index 945fd71..bc930d0 100644 --- a/provider.go +++ b/contentful/provider.go @@ -1,4 +1,4 @@ -package main +package contentful import ( "os" diff --git a/provider_test.go b/contentful/provider_test.go similarity index 98% rename from provider_test.go rename to contentful/provider_test.go index 8ff6fb1..bec87e8 100644 --- a/provider_test.go +++ b/contentful/provider_test.go @@ -1,4 +1,4 @@ -package main +package contentful import ( "os" diff --git a/resource_contentful_apikey.go b/contentful/resource_contentful_apikey.go similarity index 99% rename from resource_contentful_apikey.go rename to contentful/resource_contentful_apikey.go index 2de94d7..1e9dffa 100644 --- a/resource_contentful_apikey.go +++ b/contentful/resource_contentful_apikey.go @@ -1,4 +1,4 @@ -package main +package contentful import ( "github.com/hashicorp/terraform/helper/schema" diff --git a/resource_contentful_apikey_test.go b/contentful/resource_contentful_apikey_test.go similarity index 99% rename from resource_contentful_apikey_test.go rename to contentful/resource_contentful_apikey_test.go index 2b76185..0639b09 100644 --- a/resource_contentful_apikey_test.go +++ b/contentful/resource_contentful_apikey_test.go @@ -1,4 +1,4 @@ -package main +package contentful import ( "fmt" diff --git a/resource_contentful_contenttype.go b/contentful/resource_contentful_contenttype.go similarity index 99% rename from resource_contentful_contenttype.go rename to contentful/resource_contentful_contenttype.go index 116932e..8b90c63 100644 --- a/resource_contentful_contenttype.go +++ b/contentful/resource_contentful_contenttype.go @@ -1,4 +1,4 @@ -package main +package contentful import ( "github.com/hashicorp/terraform/helper/schema" diff --git a/resource_contentful_contenttype_test.go b/contentful/resource_contentful_contenttype_test.go similarity index 99% rename from resource_contentful_contenttype_test.go rename to contentful/resource_contentful_contenttype_test.go index fa1afdb..823d28b 100644 --- a/resource_contentful_contenttype_test.go +++ b/contentful/resource_contentful_contenttype_test.go @@ -1,4 +1,4 @@ -package main +package contentful import ( "fmt" diff --git a/resource_contentful_locale.go b/contentful/resource_contentful_locale.go similarity index 99% rename from resource_contentful_locale.go rename to contentful/resource_contentful_locale.go index 1c51b50..366f17f 100644 --- a/resource_contentful_locale.go +++ b/contentful/resource_contentful_locale.go @@ -1,4 +1,4 @@ -package main +package contentful import ( "github.com/hashicorp/terraform/helper/schema" diff --git a/resource_contentful_locale_test.go b/contentful/resource_contentful_locale_test.go similarity index 99% rename from resource_contentful_locale_test.go rename to contentful/resource_contentful_locale_test.go index b4ba1b6..c6241e6 100644 --- a/resource_contentful_locale_test.go +++ b/contentful/resource_contentful_locale_test.go @@ -1,4 +1,4 @@ -package main +package contentful import ( "fmt" diff --git a/resource_contentful_space.go b/contentful/resource_contentful_space.go similarity index 99% rename from resource_contentful_space.go rename to contentful/resource_contentful_space.go index 0f7288c..eb77101 100644 --- a/resource_contentful_space.go +++ b/contentful/resource_contentful_space.go @@ -1,4 +1,4 @@ -package main +package contentful import ( "github.com/hashicorp/terraform/helper/schema" diff --git a/resource_contentful_space_test.go b/contentful/resource_contentful_space_test.go similarity index 98% rename from resource_contentful_space_test.go rename to contentful/resource_contentful_space_test.go index f52b856..56341b1 100644 --- a/resource_contentful_space_test.go +++ b/contentful/resource_contentful_space_test.go @@ -1,4 +1,4 @@ -package main +package contentful import ( "fmt" diff --git a/resource_contentful_webhook.go b/contentful/resource_contentful_webhook.go similarity index 99% rename from resource_contentful_webhook.go rename to contentful/resource_contentful_webhook.go index 60f338a..fbb2351 100644 --- a/resource_contentful_webhook.go +++ b/contentful/resource_contentful_webhook.go @@ -1,4 +1,4 @@ -package main +package contentful import ( "github.com/hashicorp/terraform/helper/schema" diff --git a/resource_contentful_webhook_test.go b/contentful/resource_contentful_webhook_test.go similarity index 99% rename from resource_contentful_webhook_test.go rename to contentful/resource_contentful_webhook_test.go index a4a6bb3..005ebf2 100644 --- a/resource_contentful_webhook_test.go +++ b/contentful/resource_contentful_webhook_test.go @@ -1,4 +1,4 @@ -package main +package contentful import ( "fmt" diff --git a/install-dependencies.sh b/install-dependencies.sh deleted file mode 100755 index 64a0a61..0000000 --- a/install-dependencies.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env bash -# Let's avoid rebuilding the dependencies each time a source file changes. -# See: http://stackoverflow.com/questions/39278756/cache-go-get-in-docker-build -go get github.com/hashicorp/terraform/terraform -go get github.com/hashicorp/terraform/helper/resource -go get github.com/hashicorp/terraform/helper/schema -go get github.com/labd/contentful-go diff --git a/main.go b/main.go index 5ecf31e..ff4faff 100644 --- a/main.go +++ b/main.go @@ -3,12 +3,13 @@ package main import ( "github.com/hashicorp/terraform/plugin" "github.com/hashicorp/terraform/terraform" + "github.com/labd/terraform-contentful/contentful" ) func main() { plugin.Serve(&plugin.ServeOpts{ ProviderFunc: func() terraform.ResourceProvider { - return Provider() + return contentful.Provider() }, }) } From 0f77eceaa376ceaaed87aee332c328e2af69c7a9 Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Thu, 16 Apr 2020 14:31:17 +0200 Subject: [PATCH 097/192] Minor changes The space resource is now skipped while testing. This is because I, along with many other Contentful users do not have permissions to change, create or delete spaces within an organization. The Space resource test will fail in this case, so for now it is skipped. --- Makefile | 29 +++++++++++-------- contentful/resource_contentful_space_test.go | 3 +- .../resource_contentful_webhook_test.go | 16 ++-------- tools/install-dependencies.sh | 6 ++++ tools/test.sh | 20 +++++++++++++ 5 files changed, 48 insertions(+), 26 deletions(-) create mode 100755 tools/install-dependencies.sh create mode 100755 tools/test.sh diff --git a/Makefile b/Makefile index c7af448..3b8d599 100644 --- a/Makefile +++ b/Makefile @@ -1,16 +1,21 @@ -build: - go build -o terraform-provider-contentful +GO_CMD=go +GO_BUILD=$(GO_CMD) build +GO_BUILD_RACE=$(GO_CMD) build -race +GO_TEST=$(GO_CMD) test +GO_TEST_VERBOSE=$(GO_CMD) test -v +GO_INSTALL=$(GO_CMD) install -v +GO_CLEAN=$(GO_CMD) clean +GO_DEPS=$(GO_CMD) get -d -v +GO_DEPS_UPDATE=$(GO_CMD) get -d -v -u +GO_VET=$(GO_CMD) vet +GO_FMT=$(GO_CMD) fmt -format: - go fmt ./... +.PHONY: all test format dep -test: - TF_ACC=1 go test -v +all: dep test format -coverage-html: - go test -race -coverprofile=coverage.txt -covermode=atomic -coverpkg=./... ./... - go tool cover -html=coverage.txt +test: + ./tools/test.sh -coverage: - go test -race -coverprofile=coverage.txt -covermode=atomic -coverpkg=./... ./... - go tool cover -func=coverage.txt +format: + go fmt diff --git a/contentful/resource_contentful_space_test.go b/contentful/resource_contentful_space_test.go index 56341b1..b82cdf8 100644 --- a/contentful/resource_contentful_space_test.go +++ b/contentful/resource_contentful_space_test.go @@ -10,6 +10,7 @@ import ( ) func TestAccContentfulSpace_Basic(t *testing.T) { + t.Skip() // Space resource can only be tested when user has the rights to do so, if not, skip this test! resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, @@ -48,7 +49,7 @@ func testAccCheckContentfulSpaceDestroy(s *terraform.State) error { var testAccContentfulSpaceConfig = ` resource "contentful_space" "myspace" { - name = "TF Acc Test Space" + name = "Playground" } ` diff --git a/contentful/resource_contentful_webhook_test.go b/contentful/resource_contentful_webhook_test.go index 005ebf2..32d3195 100644 --- a/contentful/resource_contentful_webhook_test.go +++ b/contentful/resource_contentful_webhook_test.go @@ -131,13 +131,8 @@ func testAccContentfulWebhookDestroy(s *terraform.State) error { } var testAccContentfulWebhookConfig = ` -resource "contentful_space" "myspace" { - name = "space-name" -} - resource "contentful_webhook" "mywebhook" { - space_id = "${contentful_space.myspace.id}" - depends_on = ["contentful_space.myspace"] + space_id = "uhwvl4veejyj" name = "webhook-name" url= "https://www.example.com/test" @@ -145,7 +140,7 @@ resource "contentful_webhook" "mywebhook" { "Entry.create", "ContentType.create", ] - headers { + headers = { header1 = "header1-value" header2 = "header2-value" } @@ -155,13 +150,8 @@ resource "contentful_webhook" "mywebhook" { ` var testAccContentfulWebhookUpdateConfig = ` -resource "contentful_space" "myspace" { - name = "space-name" -} - resource "contentful_webhook" "mywebhook" { - depends_on = ["contentful_space.myspace"] - space_id = "${contentful_space.myspace.id}" + space_id = "uhwvl4veejyj" name = "webhook-name-updated" url= "https://www.example.com/test-updated" diff --git a/tools/install-dependencies.sh b/tools/install-dependencies.sh new file mode 100755 index 0000000..e2c4911 --- /dev/null +++ b/tools/install-dependencies.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +go get github.com/hashicorp/terraform/terraform +go get github.com/hashicorp/terraform/helper/resource +go get github.com/hashicorp/terraform/helper/schema +go get github.com/labd/contentful-go diff --git a/tools/test.sh b/tools/test.sh new file mode 100755 index 0000000..f2234f1 --- /dev/null +++ b/tools/test.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash +set -e + +rm coverage.txt || true +touch coverage.txt + +for d in $(go list ./... | grep -v /vendor/); do + TF_ACC=1 go test -v -coverprofile=profile.out -covermode=count "$d" + + if [ -f profile.out ]; then + cat profile.out >> coverage.txt + rm profile.out + fi +done + +# to make `go tool cover -html=coverage.txt` happy +# remove the lines starting with mode +# remove the empty lines +sed -i'' -e '/^\s*$/d' coverage.txt +echo "$(awk '!/^mode:/ || !f++' coverage.txt)" > coverage.txt From 0eb15e9a712c82aee418a178c255f36a4338539b Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Thu, 16 Apr 2020 16:15:49 +0200 Subject: [PATCH 098/192] Space id to environment variable Changed space id into an environment variable. --- contentful/constants.go | 2 ++ contentful/resource_contentful_apikey_test.go | 10 ++++++---- contentful/resource_contentful_contenttype_test.go | 8 ++++---- contentful/resource_contentful_locale_test.go | 6 ++++-- contentful/resource_contentful_webhook_test.go | 7 +++++-- 5 files changed, 21 insertions(+), 12 deletions(-) diff --git a/contentful/constants.go b/contentful/constants.go index 3bff800..3beaa75 100644 --- a/contentful/constants.go +++ b/contentful/constants.go @@ -2,12 +2,14 @@ package contentful import ( "errors" + "os" ) // noinspection GoUnusedGlobalVariable var ( baseURL = "https://api.contentful.com" contentfulContentType = "application/vnd.contentful.management.v1+json" + spaceID = os.Getenv("SPACE_ID") // User friendly errors we return errorUnauthorized = errors.New("401 Unauthorized. Is the CMA token valid") errorSpaceNotFound = errors.New("space not found") diff --git a/contentful/resource_contentful_apikey_test.go b/contentful/resource_contentful_apikey_test.go index 0639b09..b8a3160 100644 --- a/contentful/resource_contentful_apikey_test.go +++ b/contentful/resource_contentful_apikey_test.go @@ -26,6 +26,7 @@ func TestAccContentfulAPIKey_Basic(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckContentfulAPIKeyExists("contentful_apikey.myapikey", &apiKey), testAccCheckContentfulAPIKeyAttributes(&apiKey, map[string]interface{}{ + "space_id": spaceID, "name": name, "description": description, }), @@ -36,6 +37,7 @@ func TestAccContentfulAPIKey_Basic(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckContentfulAPIKeyExists("contentful_apikey.myapikey", &apiKey), testAccCheckContentfulAPIKeyAttributes(&apiKey, map[string]interface{}{ + "space_id": spaceID, "name": fmt.Sprintf("%s-updated", name), "description": fmt.Sprintf("%s-updated", description), }), @@ -124,21 +126,21 @@ func testAccContentfulAPIKeyDestroy(s *terraform.State) error { func testAccContentfulAPIKeyConfig(name, description string) string { return fmt.Sprintf(` resource "contentful_apikey" "myapikey" { - space_id = "uhwvl4veejyj" + space_id = "%s" name = "%s" description = "%s" } -`, name, description) +`, spaceID, name, description) } func testAccContentfulAPIKeyUpdateConfig(name, description string) string { return fmt.Sprintf(` resource "contentful_apikey" "myapikey" { - space_id = "uhwvl4veejyj" + space_id = "%s" name = "%s-updated" description = "%s-updated" } -`, name, description) +`, spaceID, name, description) } diff --git a/contentful/resource_contentful_contenttype_test.go b/contentful/resource_contentful_contenttype_test.go index 823d28b..298624a 100644 --- a/contentful/resource_contentful_contenttype_test.go +++ b/contentful/resource_contentful_contenttype_test.go @@ -90,7 +90,7 @@ func testAccCheckContentfulContentTypeDestroy(s *terraform.State) (err error) { var testAccContentfulContentTypeConfig = ` resource "contentful_contenttype" "mycontenttype" { - space_id = "uhwvl4veejyj" + space_id = "` + spaceID + `" name = "TF Acc Test CT 1" description = "Terraform Acc Test Content Type" display_field = "field1" @@ -117,7 +117,7 @@ resource "contentful_contenttype" "mycontenttype" { var testAccContentfulContentTypeUpdateConfig = ` resource "contentful_contenttype" "mycontenttype" { - space_id = "uhwvl4veejyj" + space_id = "` + spaceID + `" name = "TF Acc Test CT name change" description = "Terraform Acc Test Content Type description change" display_field = "field1" @@ -144,7 +144,7 @@ resource "contentful_contenttype" "mycontenttype" { var testAccContentfulContentTypeLinkConfig = ` resource "contentful_contenttype" "mycontenttype" { - space_id = "uhwvl4veejyj" + space_id = "` + spaceID + `" name = "TF Acc Test CT name change" description = "Terraform Acc Test Content Type description change" display_field = "field1" @@ -169,7 +169,7 @@ resource "contentful_contenttype" "mycontenttype" { } resource "contentful_contenttype" "mylinked_contenttype" { - space_id = "uhwvl4veejyj" + space_id = "` + spaceID + `" name = "TF Acc Test Linked CT" description = "Terraform Acc Test Content Type with links" display_field = "asset_field" diff --git a/contentful/resource_contentful_locale_test.go b/contentful/resource_contentful_locale_test.go index c6241e6..8afe7f3 100644 --- a/contentful/resource_contentful_locale_test.go +++ b/contentful/resource_contentful_locale_test.go @@ -22,6 +22,7 @@ func TestAccContentfulLocales_Basic(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckContentfulLocaleExists("contentful_locale.mylocale", &locale), testAccCheckContentfulLocaleAttributes(&locale, map[string]interface{}{ + "space_id": spaceID, "name": "locale-name", "code": "de", "fallback_code": "en-US", @@ -36,6 +37,7 @@ func TestAccContentfulLocales_Basic(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckContentfulLocaleExists("contentful_locale.mylocale", &locale), testAccCheckContentfulLocaleAttributes(&locale, map[string]interface{}{ + "space_id": spaceID, "name": "locale-name-updated", "code": "es", "fallback_code": "en-US", @@ -146,7 +148,7 @@ func testAccContentfulLocaleDestroy(s *terraform.State) error { var testAccContentfulLocaleConfig = ` resource "contentful_locale" "mylocale" { - space_id = "uhwvl4veejyj" + space_id = "` + spaceID + `" name = "locale-name" code = "de" @@ -159,7 +161,7 @@ resource "contentful_locale" "mylocale" { var testAccContentfulLocaleUpdateConfig = ` resource "contentful_locale" "mylocale" { - space_id = "uhwvl4veejyj" + space_id = "` + spaceID + `" name = "locale-name-updated" code = "es" diff --git a/contentful/resource_contentful_webhook_test.go b/contentful/resource_contentful_webhook_test.go index 32d3195..16a39eb 100644 --- a/contentful/resource_contentful_webhook_test.go +++ b/contentful/resource_contentful_webhook_test.go @@ -22,6 +22,7 @@ func TestAccContentfulWebhook_Basic(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckContentfulWebhookExists("contentful_webhook.mywebhook", &webhook), testAccCheckContentfulWebhookAttributes(&webhook, map[string]interface{}{ + "space_id": spaceID, "name": "webhook-name", "url": "https://www.example.com/test", "http_basic_auth_username": "username", @@ -33,6 +34,7 @@ func TestAccContentfulWebhook_Basic(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckContentfulWebhookExists("contentful_webhook.mywebhook", &webhook), testAccCheckContentfulWebhookAttributes(&webhook, map[string]interface{}{ + "space_id": spaceID, "name": "webhook-name-updated", "url": "https://www.example.com/test-updated", "http_basic_auth_username": "username-updated", @@ -132,7 +134,7 @@ func testAccContentfulWebhookDestroy(s *terraform.State) error { var testAccContentfulWebhookConfig = ` resource "contentful_webhook" "mywebhook" { - space_id = "uhwvl4veejyj" + space_id = "` + spaceID + `" name = "webhook-name" url= "https://www.example.com/test" @@ -151,7 +153,8 @@ resource "contentful_webhook" "mywebhook" { var testAccContentfulWebhookUpdateConfig = ` resource "contentful_webhook" "mywebhook" { - space_id = "uhwvl4veejyj" + space_id = "` + spaceID + `" + name = "webhook-name-updated" url= "https://www.example.com/test-updated" From b88a2b07a42119d75320836f42b0120dc4d94896 Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Fri, 17 Apr 2020 11:21:29 +0200 Subject: [PATCH 099/192] Docker working Updated the config and makefile to work with the newest versions of Docker and GO --- .circleci/config.yml | 15 +++++++ .github/workflows/go.yml | 40 +++++++++++++++++++ .gitignore | 2 +- Dockerfile-test | 11 +++++ Makefile | 40 +++++++++++-------- ...dependencies.sh => install-dependencies.sh | 0 6 files changed, 90 insertions(+), 18 deletions(-) create mode 100644 .circleci/config.yml create mode 100644 .github/workflows/go.yml create mode 100644 Dockerfile-test rename tools/install-dependencies.sh => install-dependencies.sh (100%) diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000..05e4088 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,15 @@ +machine: + pre: + # Install docker 1.10.0, can be removed when circle ships it + # https://discuss.circleci.com/t/docker-1-10-0-is-available-beta/2100 + - curl -sSL https://s3.amazonaws.com/circle-downloads/install-circleci-docker.sh | bash -s -- 1.10.0 + services: + - docker + +dependencies: + override: + - make build + +test: + override: + - make test-unit \ No newline at end of file diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml new file mode 100644 index 0000000..47e1a3d --- /dev/null +++ b/.github/workflows/go.yml @@ -0,0 +1,40 @@ +name: Go + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + + build: + name: Build + runs-on: ubuntu-latest + steps: + + - name: Set up Go 1.9 + uses: actions/setup-go@v1 + with: + go-version: 1.9 + id: go + + - name: Check out code into the Go module directory + uses: actions/checkout@v2 + + - name: Get dependencies + run: | + go get -v -t -d ./... + if [ -f Gopkg.toml ]; then + curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh + dep ensure + fi + - name: Build + run: go build -v . + test: + name: Test + runs-on: ubuntu-latest + needs: [build] + steps: + - name: Test + run: go test -v . \ No newline at end of file diff --git a/.gitignore b/.gitignore index 3c647cf..15dc197 100644 --- a/.gitignore +++ b/.gitignore @@ -13,7 +13,7 @@ crash.log .vscode .idea -/local/* +local/ !/local/*.example vendor/ \ No newline at end of file diff --git a/Dockerfile-test b/Dockerfile-test new file mode 100644 index 0000000..c03abc1 --- /dev/null +++ b/Dockerfile-test @@ -0,0 +1,11 @@ +FROM golang:1.14.2 + +WORKDIR /go/src/github.com/labd/terraform-contentful + +# http://stackoverflow.com/questions/39278756/cache-go-get-in-docker-build +COPY ./install-dependencies.sh /go/src/github.com/labd/terraform-contentful +RUN ./install-dependencies.sh + +COPY . /go/src/github.com/labd/terraform-contentful + +CMD go test -v \ No newline at end of file diff --git a/Makefile b/Makefile index 3b8d599..bfaf9e0 100644 --- a/Makefile +++ b/Makefile @@ -1,21 +1,27 @@ -GO_CMD=go -GO_BUILD=$(GO_CMD) build -GO_BUILD_RACE=$(GO_CMD) build -race -GO_TEST=$(GO_CMD) test -GO_TEST_VERBOSE=$(GO_CMD) test -v -GO_INSTALL=$(GO_CMD) install -v -GO_CLEAN=$(GO_CMD) clean -GO_DEPS=$(GO_CMD) get -d -v -GO_DEPS_UPDATE=$(GO_CMD) get -d -v -u -GO_VET=$(GO_CMD) vet -GO_FMT=$(GO_CMD) fmt +GOCMD=go +CMT=$(GOCMD) os.Getenv("CONTENTFUL_MANAGEMENT_TOKEN") -.PHONY: all test format dep -all: dep test format +.PHONY: build +build: + sudo -S docker build -t terraform-provider-contentful -f Dockerfile-test . -test: - ./tools/test.sh +.PHONY: test-unit +test-unit: build + sudo docker run \ + -e CONTENTFUL_MANAGEMENT_TOKEN=${CONTENTFUL_MANAGEMENT_TOKEN} \ + -e CONTENTFUL_ORGANIZATION_ID=${CONTENTFUL_ORGANIZATION_ID} \ + -e SPACE_ID=${SPACE_ID} \ + -e "TF_ACC=true" \ + terraform-provider-contentful \ + go test ./... -v -format: - go fmt +.PHONY: interactive +interactive: + sudo -S docker run -it \ + -v $(shell pwd):/go/src/github.com/labd/terraform-contentful \ + -e CONTENTFUL_MANAGEMENT_TOKEN=${CONTENTFUL_MANAGEMENT_TOKEN} \ + -e CONTENTFUL_ORGANIZATION_ID=${CONTENTFUL_ORGANIZATION_ID} \ + -e SPACE_ID=${SPACE_ID} \ + terraform-provider-contentful \ + bash diff --git a/tools/install-dependencies.sh b/install-dependencies.sh similarity index 100% rename from tools/install-dependencies.sh rename to install-dependencies.sh From 8163d150f65ea588f3548fa91bccbe6f1c12f2cd Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Fri, 17 Apr 2020 11:22:33 +0200 Subject: [PATCH 100/192] removed some redundant code --- Makefile | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Makefile b/Makefile index bfaf9e0..3b44a7a 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,3 @@ -GOCMD=go -CMT=$(GOCMD) os.Getenv("CONTENTFUL_MANAGEMENT_TOKEN") - - .PHONY: build build: sudo -S docker build -t terraform-provider-contentful -f Dockerfile-test . From 9f2e0bfeaeb2da145c7d66155b30db330115230c Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Mon, 20 Apr 2020 11:29:45 +0200 Subject: [PATCH 101/192] go mod versioning fix --- go.mod | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 go.mod diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..f56f7b6 --- /dev/null +++ b/go.mod @@ -0,0 +1,8 @@ +module github.com/labd/terraform-contentful + +go 1.14 + +require ( + github.com/hashicorp/terraform v0.12.24 + github.com/labd/contentful-go v0.4.1-0.20200420081834-f20ec0d2853f +) From 03ea07f843b73cd6c8c6f6f3f436aedeb2a46b7a Mon Sep 17 00:00:00 2001 From: Jasper Berghoef Date: Thu, 16 Apr 2020 16:11:02 +0200 Subject: [PATCH 102/192] Create go.yml --- .github/workflows/go.yml | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 47e1a3d..717a57b 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -13,28 +13,28 @@ jobs: runs-on: ubuntu-latest steps: - - name: Set up Go 1.9 - uses: actions/setup-go@v1 - with: - go-version: 1.9 - id: go + - name: Set up Go 1.13 + uses: actions/setup-go@v1 + with: + go-version: 1.13 + id: go - - name: Check out code into the Go module directory - uses: actions/checkout@v2 + - name: Check out code into the Go module directory + uses: actions/checkout@v2 - - name: Get dependencies - run: | - go get -v -t -d ./... - if [ -f Gopkg.toml ]; then - curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh - dep ensure - fi - - name: Build - run: go build -v . + - name: Get dependencies + run: | + go get -v -t -d ./... + if [ -f Gopkg.toml ]; then + curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh + dep ensure + fi + + - name: Build + run: go build -v . test: name: Test runs-on: ubuntu-latest - needs: [build] steps: - name: Test - run: go test -v . \ No newline at end of file + run: go test -v . From 7d905fa3fe14a0db54c01c5e93473bfa4aa87ae6 Mon Sep 17 00:00:00 2001 From: Jasper Berghoef Date: Thu, 16 Apr 2020 16:13:40 +0200 Subject: [PATCH 103/192] Update go.yml --- .github/workflows/go.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 717a57b..b8a214f 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -13,10 +13,10 @@ jobs: runs-on: ubuntu-latest steps: - - name: Set up Go 1.13 + - name: Set up Go 1.9 uses: actions/setup-go@v1 with: - go-version: 1.13 + go-version: 1.9 id: go - name: Check out code into the Go module directory @@ -35,6 +35,7 @@ jobs: test: name: Test runs-on: ubuntu-latest + needs: [build] steps: - name: Test run: go test -v . From e681c3fcfa2afa4a61e2c135626a87957bed88a4 Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Mon, 20 Apr 2020 11:47:33 +0200 Subject: [PATCH 104/192] go test wildcard fix --- .github/workflows/go.yml | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index b8a214f..24909e7 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -13,29 +13,28 @@ jobs: runs-on: ubuntu-latest steps: - - name: Set up Go 1.9 - uses: actions/setup-go@v1 - with: - go-version: 1.9 - id: go + - name: Set up Go 1.14.2 + uses: actions/setup-go@v1 + with: + go-version: 1.14.2 + id: go - - name: Check out code into the Go module directory - uses: actions/checkout@v2 + - name: Check out code into the Go module directory + uses: actions/checkout@v2 - - name: Get dependencies - run: | - go get -v -t -d ./... - if [ -f Gopkg.toml ]; then - curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh - dep ensure - fi - - - name: Build - run: go build -v . + - name: Get dependencies + run: | + go get -v -t -d ./... + if [ -f Gopkg.toml ]; then + curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh + dep ensure + fi + - name: Build + run: go build -v . test: name: Test runs-on: ubuntu-latest needs: [build] steps: - name: Test - run: go test -v . + run: go test ./... -v From 82cfadffab3902f31ce12fbb3e18483f2ac1ec32 Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Mon, 20 Apr 2020 13:59:10 +0200 Subject: [PATCH 105/192] test config change --- .github/workflows/go.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 24909e7..7ae1bec 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -36,5 +36,9 @@ jobs: runs-on: ubuntu-latest needs: [build] steps: - - name: Test - run: go test ./... -v + - name: Install dependencies + run: go get ./contentful + - name: Run tests + run: go test -race -coverprofile=coverage.txt -covermode=atomic -coverpkg=./contentful -v ./contentful + - name: Upload to codecov + uses: codecov/codecov-action@v1.0.6 From f7be769c0a1ffccfcc2c31c35007913dd245a1fb Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Mon, 20 Apr 2020 14:17:06 +0200 Subject: [PATCH 106/192] test config change --- .github/workflows/go.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 7ae1bec..d6aa587 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -36,9 +36,21 @@ jobs: runs-on: ubuntu-latest needs: [build] steps: + + - name: Set up Go 1.14.2 + uses: actions/setup-go@v1 + with: + go-version: 1.14.2 + id: go + + - name: Check out code into the Go module directory + uses: actions/checkout@v2 + - name: Install dependencies run: go get ./contentful + - name: Run tests run: go test -race -coverprofile=coverage.txt -covermode=atomic -coverpkg=./contentful -v ./contentful + - name: Upload to codecov uses: codecov/codecov-action@v1.0.6 From 6d60d2ec60cb8cfc6f846033ae89797d0e636304 Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Mon, 20 Apr 2020 14:19:24 +0200 Subject: [PATCH 107/192] test config change --- .github/workflows/go.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index d6aa587..0d2c851 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -47,10 +47,10 @@ jobs: uses: actions/checkout@v2 - name: Install dependencies - run: go get ./contentful + run: go get ./contentful - name: Run tests - run: go test -race -coverprofile=coverage.txt -covermode=atomic -coverpkg=./contentful -v ./contentful + run: go test -race -coverprofile=coverage.txt -covermode=atomic -coverpkg=./contentful -v ./contentful - name: Upload to codecov - uses: codecov/codecov-action@v1.0.6 + uses: codecov/codecov-action@v1.0.6 \ No newline at end of file From 5fae27f59388140f2cb421d6f69f9160fc49c259 Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Mon, 20 Apr 2020 14:37:48 +0200 Subject: [PATCH 108/192] test config change --- .github/workflows/go.yml | 66 ++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 37 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 0d2c851..cc4be5f 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -12,45 +12,37 @@ jobs: name: Build runs-on: ubuntu-latest steps: - - - name: Set up Go 1.14.2 - uses: actions/setup-go@v1 - with: - go-version: 1.14.2 - id: go - - - name: Check out code into the Go module directory - uses: actions/checkout@v2 - - - name: Get dependencies - run: | - go get -v -t -d ./... - if [ -f Gopkg.toml ]; then - curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh - dep ensure - fi - - name: Build - run: go build -v . + - name: Set up Go 1.14.2 + uses: actions/setup-go@v1 + with: + go-version: 1.14.2 + id: go + - name: Check out code into the Go module directory + uses: actions/checkout@v2 + - name: Get dependencies + run: | + go get -v -t -d ./... + if [ -f Gopkg.toml ]; then + curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh + dep ensure + fi + - name: Build + run: go build -v . test: name: Test runs-on: ubuntu-latest needs: [build] steps: - - - name: Set up Go 1.14.2 - uses: actions/setup-go@v1 - with: - go-version: 1.14.2 - id: go - - - name: Check out code into the Go module directory - uses: actions/checkout@v2 - - - name: Install dependencies - run: go get ./contentful - - - name: Run tests - run: go test -race -coverprofile=coverage.txt -covermode=atomic -coverpkg=./contentful -v ./contentful - - - name: Upload to codecov - uses: codecov/codecov-action@v1.0.6 \ No newline at end of file + - name: Set up Go 1.14.2 + uses: actions/setup-go@v1 + with: + go-version: 1.14.2 + id: go + - name: Check out code into the Go module directory + uses: actions/checkout@v2 + - name: Install dependencies + run: go get ./contentful + - name: Run tests + run: go test -race -coverprofile=coverage.txt -covermode=atomic -coverpkg=./contentful -v ./contentful + - name: Upload to codecov + uses: codecov/codecov-action@v1.0.6 \ No newline at end of file From 44857e52e9210cf94f1ab885a93fdc9f8f83dd41 Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Mon, 20 Apr 2020 16:14:25 +0200 Subject: [PATCH 109/192] test config now using secrets as environment variables for tests. --- .github/workflows/go.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index cc4be5f..f465df4 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -44,5 +44,9 @@ jobs: run: go get ./contentful - name: Run tests run: go test -race -coverprofile=coverage.txt -covermode=atomic -coverpkg=./contentful -v ./contentful + env: + CONTENTFUL_ORGANIZATION_ID: ${{ secrets.CONTENTFUL_ORGANIZATION_ID }} + CONTENTFUL_MANAGEMENT_TOKEN: ${{ secrets.CONTENTFUL_MANAGEMENT_TOKEN }} + SPACE_ID: ${{ secrets.SPACE_ID }} - name: Upload to codecov uses: codecov/codecov-action@v1.0.6 \ No newline at end of file From 40328cabf9d7d9a528c68166c3f64dfd8be15dd5 Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Mon, 20 Apr 2020 16:19:42 +0200 Subject: [PATCH 110/192] Terraform account boolean now set to True/1 --- .github/workflows/go.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index f465df4..5b709ae 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -45,6 +45,7 @@ jobs: - name: Run tests run: go test -race -coverprofile=coverage.txt -covermode=atomic -coverpkg=./contentful -v ./contentful env: + TF_ACC: 1 CONTENTFUL_ORGANIZATION_ID: ${{ secrets.CONTENTFUL_ORGANIZATION_ID }} CONTENTFUL_MANAGEMENT_TOKEN: ${{ secrets.CONTENTFUL_MANAGEMENT_TOKEN }} SPACE_ID: ${{ secrets.SPACE_ID }} From 13d63eb042cf35dfa8fd619d33f3b221b47435d4 Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Mon, 20 Apr 2020 16:44:49 +0200 Subject: [PATCH 111/192] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4ddae03..d797c8c 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -[![Build Status](https://img.shields.io/circleci/project/github/contentful-labs/terraform-contentful.svg?branch=master)](https://circleci.com/gh/contentful-labs/terraform-contentful) -[![license](https://img.shields.io/github/license/contentful-labs/terraform-contentful.svg)](https://github.com/contentful-labs/terraform-contentful/blob/master/LICENSE) +[![Build Status](https://img.shields.io/circleci/project/github/labd/terraform-contentful.svg?branch=master)](https://circleci.com/gh/labd/terraform-contentful) +[![license](https://img.shields.io/github/license/contentful-labs/terraform-contentful.svg)](https://github.com/labd/terraform-contentful/blob/master/LICENSE) Terraform Provider for [Contentful's](https://www.contentful.com) Content Management API From fe694a2c5dfc5d0ebef4d0f1321bcd37d923fd17 Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Mon, 20 Apr 2020 16:57:12 +0200 Subject: [PATCH 112/192] Updated ReadMe to display correct project data. --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d797c8c..084df05 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ -[![Build Status](https://img.shields.io/circleci/project/github/labd/terraform-contentful.svg?branch=master)](https://circleci.com/gh/labd/terraform-contentful) +![Go](https://github.com/labd/terraform-contentful/workflows/Go/badge.svg?branch=master) +[![codecov](https://codecov.io/gh/labd/terraform-contentful/branch/master/graph/badge.svg)](https://codecov.io/gh/labd/terraform-contentful) [![license](https://img.shields.io/github/license/contentful-labs/terraform-contentful.svg)](https://github.com/labd/terraform-contentful/blob/master/LICENSE) Terraform Provider for [Contentful's](https://www.contentful.com) Content Management API From 32ab4f12189149c9a77dd10faa9eba3b53614082 Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Thu, 23 Apr 2020 12:22:35 +0200 Subject: [PATCH 113/192] Added Environments as resources for the provider. The provider is now able to create, read, update and delete the environments inside Contentful. --- .circleci/config.yml | 15 --- LICENSE | 2 +- README.md | 29 ++-- contentful/constants.go | 18 +-- contentful/provider.go | 8 +- contentful/provider_test.go | 5 +- contentful/resource_contentful_contenttype.go | 2 +- contentful/resource_contentful_environment.go | 120 +++++++++++++++++ .../resource_contentful_environment_test.go | 125 ++++++++++++++++++ go.mod | 2 +- tools/test.sh | 20 --- 11 files changed, 282 insertions(+), 64 deletions(-) delete mode 100644 .circleci/config.yml create mode 100644 contentful/resource_contentful_environment.go create mode 100644 contentful/resource_contentful_environment_test.go delete mode 100755 tools/test.sh diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index 05e4088..0000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,15 +0,0 @@ -machine: - pre: - # Install docker 1.10.0, can be removed when circle ships it - # https://discuss.circleci.com/t/docker-1-10-0-is-available-beta/2100 - - curl -sSL https://s3.amazonaws.com/circle-downloads/install-circleci-docker.sh | bash -s -- 1.10.0 - services: - - docker - -dependencies: - override: - - make build - -test: - override: - - make test-unit \ No newline at end of file diff --git a/LICENSE b/LICENSE index d8b47e8..38e31bc 100644 --- a/LICENSE +++ b/LICENSE @@ -14,7 +14,7 @@ copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE diff --git a/README.md b/README.md index 084df05..89d9180 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,11 @@ ![Go](https://github.com/labd/terraform-contentful/workflows/Go/badge.svg?branch=master) [![codecov](https://codecov.io/gh/labd/terraform-contentful/branch/master/graph/badge.svg)](https://codecov.io/gh/labd/terraform-contentful) -[![license](https://img.shields.io/github/license/contentful-labs/terraform-contentful.svg)](https://github.com/labd/terraform-contentful/blob/master/LICENSE) +[![license](https://img.shields.io/github/license/labd/terraform-contentful.svg)](https://github.com/labd/terraform-contentful/blob/master/LICENSE) Terraform Provider for [Contentful's](https://www.contentful.com) Content Management API # About - [Contentful](https://www.contentful.com) provides a content infrastructure for digital teams to power content in websites, apps, and devices. Unlike a CMS, Contentful was built to integrate with the modern software stack. It offers a central hub for structured content, powerful management and delivery APIs, and a customizable web app that enable developers and content creators to ship digital products faster. [Terraform](https://www.terraform.io) is a tool for building, changing, and versioning infrastructure safely and efficiently. Terraform can manage existing and popular service providers as well as custom in-house solutions. @@ -15,10 +14,12 @@ Terraform Provider for [Contentful's](https://www.contentful.com) Content Manage Create, update and delete Contentful resources such as: - [x] Spaces -- [ ] Content Types +- [x] Content Types - [x] API Keys - [x] Webhooks -- [ ] Locales +- [x] Locales +- [x] Environments +- [ ] Organizations # Getting started @@ -51,6 +52,10 @@ Build the binary $ go build -o terraform-provider-contentful +*Or using make command* + + $ make build + Add it to your ~/.terraformrc (or %APPDATA%/terraform.rc for Windows) $ cat ~/.terraformrc @@ -70,7 +75,7 @@ Use the provider by creating a main.tf file with: Run the terraform plan - terraform plan -out=contentful.plan + $ terraform plan -out=contentful.plan Check the changes ``` @@ -99,6 +104,10 @@ Plan: 1 to add, 0 to change, 0 to destroy. ``` Apply the plan + + $ terraform apply + +Check the Terraform output for warnings and errors ``` contentful_space.test: Creating... default_locale: "" => "en" @@ -118,11 +127,15 @@ State path: ## Testing - TF_ACC=1 go test -v + $ TF_ACC=1 go test -v + +To enable higher verbose mode: + + $ TF_LOG=debug TF_ACC=1 go test -v -To enable higher verbose mode +For testing, you can also make use of the make command: - TF_LOG=debug TF_ACC=1 go test -v + $ make test-unit ## Documentation/References diff --git a/contentful/constants.go b/contentful/constants.go index 3beaa75..cff5289 100644 --- a/contentful/constants.go +++ b/contentful/constants.go @@ -1,19 +1,15 @@ package contentful import ( - "errors" "os" ) -// noinspection GoUnusedGlobalVariable var ( - baseURL = "https://api.contentful.com" - contentfulContentType = "application/vnd.contentful.management.v1+json" - spaceID = os.Getenv("SPACE_ID") - // User friendly errors we return - errorUnauthorized = errors.New("401 Unauthorized. Is the CMA token valid") - errorSpaceNotFound = errors.New("space not found") - errorOrganizationNotFound = errors.New("organization not found") - errorLocaleNotFound = errors.New("locale not found") - errorWebhookNotFound = errors.New("the webhook could not be found") + // Environment variables + spaceID = os.Getenv("SPACE_ID") + CMAToken = os.Getenv("CONTENTFUL_MANAGEMENT_TOKEN") + orgID = os.Getenv("CONTENTFUL_ORGANIZATION_ID") + + // Terraform configuration values + logBoolean = os.Getenv("TF_LOG") ) diff --git a/contentful/provider.go b/contentful/provider.go index bc930d0..55e5f66 100644 --- a/contentful/provider.go +++ b/contentful/provider.go @@ -1,14 +1,12 @@ package contentful import ( - "os" - "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/terraform" contentful "github.com/labd/contentful-go" ) -// Provider does shit +// Provider returns the Terraform Provider as a scheme and makes resources reachable func Provider() terraform.ResourceProvider { return &schema.Provider{ Schema: map[string]*schema.Schema{ @@ -31,16 +29,18 @@ func Provider() terraform.ResourceProvider { "contentful_apikey": resourceContentfulAPIKey(), "contentful_webhook": resourceContentfulWebhook(), "contentful_locale": resourceContentfulLocale(), + "contentful_environment": resourceContentfulEnvironment(), }, ConfigureFunc: providerConfigure, } } +// providerConfigure sets the configuration for the Terraform Provider func providerConfigure(d *schema.ResourceData) (interface{}, error) { cma := contentful.NewCMA(d.Get("cma_token").(string)) cma.SetOrganization(d.Get("organization_id").(string)) - if os.Getenv("TF_LOG") != "" { + if logBoolean != "" { cma.Debug = true } diff --git a/contentful/provider_test.go b/contentful/provider_test.go index bec87e8..44bdb5a 100644 --- a/contentful/provider_test.go +++ b/contentful/provider_test.go @@ -1,7 +1,6 @@ package contentful import ( - "os" "testing" "github.com/hashicorp/terraform/helper/schema" @@ -30,10 +29,10 @@ func TestProvider_impl(t *testing.T) { func testAccPreCheck(t *testing.T) { var cmaToken, organizationID string - if cmaToken = os.Getenv("CONTENTFUL_MANAGEMENT_TOKEN"); cmaToken == "" { + if cmaToken = CMAToken; cmaToken == "" { t.Fatal("CONTENTFUL_MANAGEMENT_TOKEN must set with a valid Contentful Content Management API Token for acceptance tests") } - if organizationID = os.Getenv("CONTENTFUL_ORGANIZATION_ID"); organizationID == "" { + if organizationID = orgID; organizationID == "" { t.Fatal("CONTENTFUL_ORGANIZATION_ID must set with a valid Contentful Organization ID for acceptance tests") } } diff --git a/contentful/resource_contentful_contenttype.go b/contentful/resource_contentful_contenttype.go index 8b90c63..59ebf4b 100644 --- a/contentful/resource_contentful_contenttype.go +++ b/contentful/resource_contentful_contenttype.go @@ -216,7 +216,7 @@ func resourceContentTypeUpdate(d *schema.ResourceData, m interface{}) (err error } // To remove a field from a content type 4 API calls need to be made. - // Ommit the removed fields and publish the new version of the content type, + // Omit the removed fields and publish the new version of the content type, // followed by the field removal and final publish. if err = client.ContentTypes.Upsert(spaceID, ct); err != nil { return err diff --git a/contentful/resource_contentful_environment.go b/contentful/resource_contentful_environment.go new file mode 100644 index 0000000..d6f35d6 --- /dev/null +++ b/contentful/resource_contentful_environment.go @@ -0,0 +1,120 @@ +package contentful + +import ( + "github.com/hashicorp/terraform/helper/schema" + contentful "github.com/labd/contentful-go" +) + +func resourceContentfulEnvironment() *schema.Resource { + return &schema.Resource{ + Create: resourceCreateEnvironment, + Read: resourceReadEnvironment, + Update: resourceUpdateEnvironment, + Delete: resourceDeleteEnvironment, + + Schema: map[string]*schema.Schema{ + "version": { + Type: schema.TypeInt, + Computed: true, + }, + "space_id": { + Type: schema.TypeString, + Required: true, + }, + "name": { + Type: schema.TypeString, + Required: true, + }, + }, + } +} + +func resourceCreateEnvironment(d *schema.ResourceData, m interface{}) (err error) { + client := m.(*contentful.Client) + + environment := &contentful.Environment{ + Name: d.Get("name").(string), + } + + err = client.Environments.Upsert(d.Get("space_id").(string), environment) + if err != nil { + return err + } + + if err := setEnvironmentProperties(d, environment); err != nil { + return err + } + + d.SetId(environment.Name) + + return nil +} + +func resourceUpdateEnvironment(d *schema.ResourceData, m interface{}) (err error) { + client := m.(*contentful.Client) + spaceID := d.Get("space_id").(string) + environmentID := d.Id() + + environment, err := client.Environments.Get(spaceID, environmentID) + if err != nil { + return err + } + + environment.Name = d.Get("name").(string) + + err = client.Environments.Upsert(spaceID, environment) + if err != nil { + return err + } + + if err := setEnvironmentProperties(d, environment); err != nil { + return err + } + + d.SetId(environment.Sys.ID) + + return nil +} + +func resourceReadEnvironment(d *schema.ResourceData, m interface{}) (err error) { + client := m.(*contentful.Client) + spaceID := d.Get("space_id").(string) + environmentID := d.Id() + + environment, err := client.Environments.Get(spaceID, environmentID) + if _, ok := err.(contentful.NotFoundError); ok { + d.SetId("") + return nil + } + + return setEnvironmentProperties(d, environment) +} + +func resourceDeleteEnvironment(d *schema.ResourceData, m interface{}) (err error) { + client := m.(*contentful.Client) + spaceID := d.Get("space_id").(string) + environmentID := d.Id() + + environment, err := client.Environments.Get(spaceID, environmentID) + if err != nil { + return err + } + + return client.Environments.Delete(spaceID, environment) +} + +func setEnvironmentProperties(d *schema.ResourceData, environment *contentful.Environment) error { + if err := d.Set("space_id", environment.Sys.Space.Sys.ID); err != nil { + return err + } + + if err := d.Set("version", environment.Sys.Version); err != nil { + return err + } + + if err := d.Set("name", environment.Name); err != nil { + return err + } + + return nil +} diff --git a/contentful/resource_contentful_environment_test.go b/contentful/resource_contentful_environment_test.go new file mode 100644 index 0000000..c707d6d --- /dev/null +++ b/contentful/resource_contentful_environment_test.go @@ -0,0 +1,125 @@ +package contentful + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + contentful "github.com/labd/contentful-go" +) + +func TestAccContentfulEnvironment_Basic(t *testing.T) { + var environment contentful.Environment + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccContentfulEnvironmentDestroy, + Steps: []resource.TestStep{ + { + Config: testAccContentfulEnvironmentConfig, + Check: resource.ComposeTestCheckFunc( + testAccCheckContentfulEnvironmentExists("contentful_environment.myenvironment", &environment), + testAccCheckContentfulEnvironmentAttributes(&environment, map[string]interface{}{ + "space_id": spaceID, + "name": "provider-test", + }), + ), + }, + { + Config: testAccContentfulEnvironmentUpdateConfig, + Check: resource.ComposeTestCheckFunc( + testAccCheckContentfulEnvironmentExists("contentful_environment.myenvironment", &environment), + testAccCheckContentfulEnvironmentAttributes(&environment, map[string]interface{}{ + "space_id": spaceID, + "name": "provider-test-updated", + }), + ), + }, + }, + }) +} + +func testAccCheckContentfulEnvironmentExists(n string, environment *contentful.Environment) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("not Found: %s", n) + } + + spaceID := rs.Primary.Attributes["space_id"] + if spaceID == "" { + return fmt.Errorf("no space_id is set") + } + + name := rs.Primary.Attributes["name"] + if name == "" { + return fmt.Errorf("no name is set") + } + + client := testAccProvider.Meta().(*contentful.Client) + + contentfulEnvironment, err := client.Environments.Get(spaceID, rs.Primary.ID) + if err != nil { + return err + } + + *environment = *contentfulEnvironment + + return nil + } +} + +func testAccCheckContentfulEnvironmentAttributes(environment *contentful.Environment, attrs map[string]interface{}) resource.TestCheckFunc { + return func(s *terraform.State) error { + name := attrs["name"].(string) + if environment.Name != name { + return fmt.Errorf("locale name does not match: %s, %s", environment.Name, name) + } + + return nil + } +} + +func testAccContentfulEnvironmentDestroy(s *terraform.State) error { + for _, rs := range s.RootModule().Resources { + if rs.Type != "contentful_locale" { + continue + } + spaceID := rs.Primary.Attributes["space_id"] + if spaceID == "" { + return fmt.Errorf("no space_id is set") + } + + localeID := rs.Primary.ID + if localeID == "" { + return fmt.Errorf("no locale ID is set") + } + + client := testAccProvider.Meta().(*contentful.Client) + + _, err := client.Locales.Get(spaceID, localeID) + if _, ok := err.(contentful.NotFoundError); ok { + return nil + } + + return fmt.Errorf("locale still exists with id: %s", localeID) + } + + return nil +} + +var testAccContentfulEnvironmentConfig = ` +resource "contentful_environment" "myenvironment" { + space_id = "` + spaceID + `" + name = "provider-test" +} +` + +var testAccContentfulEnvironmentUpdateConfig = ` +resource "contentful_environment" "myenvironment" { + space_id = "` + spaceID + `" + name = "provider-test-updated" +} +` diff --git a/go.mod b/go.mod index f56f7b6..574b785 100644 --- a/go.mod +++ b/go.mod @@ -4,5 +4,5 @@ go 1.14 require ( github.com/hashicorp/terraform v0.12.24 - github.com/labd/contentful-go v0.4.1-0.20200420081834-f20ec0d2853f + github.com/labd/contentful-go v0.4.1-0.20200422125935-8ec49e6fa941 ) diff --git a/tools/test.sh b/tools/test.sh deleted file mode 100755 index f2234f1..0000000 --- a/tools/test.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env bash -set -e - -rm coverage.txt || true -touch coverage.txt - -for d in $(go list ./... | grep -v /vendor/); do - TF_ACC=1 go test -v -coverprofile=profile.out -covermode=count "$d" - - if [ -f profile.out ]; then - cat profile.out >> coverage.txt - rm profile.out - fi -done - -# to make `go tool cover -html=coverage.txt` happy -# remove the lines starting with mode -# remove the empty lines -sed -i'' -e '/^\s*$/d' coverage.txt -echo "$(awk '!/^mode:/ || !f++' coverage.txt)" > coverage.txt From a7b6bae6c92ddefb4fef5a50167a48f033587b85 Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Wed, 6 May 2020 17:41:29 +0200 Subject: [PATCH 114/192] Added support for entries. Created the entries resource. The entries can be created, updated and deleted. The archiving and publishing is also added into the resource, keep in mind that a resource can only be deleted when unpublished. --- contentful/provider.go | 1 + .../resource_contentful_contenttype_test.go | 14 +- contentful/resource_contentful_entry.go | 206 +++++++++++++++++ contentful/resource_contentful_entry_test.go | 207 ++++++++++++++++++ go.mod | 2 +- 5 files changed, 422 insertions(+), 8 deletions(-) create mode 100644 contentful/resource_contentful_entry.go create mode 100644 contentful/resource_contentful_entry_test.go diff --git a/contentful/provider.go b/contentful/provider.go index 55e5f66..19d95b9 100644 --- a/contentful/provider.go +++ b/contentful/provider.go @@ -30,6 +30,7 @@ func Provider() terraform.ResourceProvider { "contentful_webhook": resourceContentfulWebhook(), "contentful_locale": resourceContentfulLocale(), "contentful_environment": resourceContentfulEnvironment(), + "contentful_entry": resourceContentfulEntry(), }, ConfigureFunc: providerConfigure, } diff --git a/contentful/resource_contentful_contenttype_test.go b/contentful/resource_contentful_contenttype_test.go index 298624a..68d30cc 100644 --- a/contentful/resource_contentful_contenttype_test.go +++ b/contentful/resource_contentful_contenttype_test.go @@ -18,17 +18,17 @@ func TestAccContentfulContentType_Basic(t *testing.T) { { Config: testAccContentfulContentTypeConfig, Check: resource.TestCheckResourceAttr( - "contentful_contenttype.mycontenttype", "name", "TF Acc Test CT 1"), + "contentful_contenttype.mycontenttype", "name", "tf_test1"), }, { Config: testAccContentfulContentTypeUpdateConfig, Check: resource.TestCheckResourceAttr( - "contentful_contenttype.mycontenttype", "name", "TF Acc Test CT name change"), + "contentful_contenttype.mycontenttype", "name", "tf_test1"), }, { Config: testAccContentfulContentTypeLinkConfig, Check: resource.TestCheckResourceAttr( - "contentful_contenttype.mylinked_contenttype", "name", "TF Acc Test Linked CT"), + "contentful_contenttype.mylinked_contenttype", "name", "tf_linked"), }, }, }) @@ -91,7 +91,7 @@ func testAccCheckContentfulContentTypeDestroy(s *terraform.State) (err error) { var testAccContentfulContentTypeConfig = ` resource "contentful_contenttype" "mycontenttype" { space_id = "` + spaceID + `" - name = "TF Acc Test CT 1" + name = "tf_test1" description = "Terraform Acc Test Content Type" display_field = "field1" field { @@ -118,7 +118,7 @@ resource "contentful_contenttype" "mycontenttype" { var testAccContentfulContentTypeUpdateConfig = ` resource "contentful_contenttype" "mycontenttype" { space_id = "` + spaceID + `" - name = "TF Acc Test CT name change" + name = "tf_test1" description = "Terraform Acc Test Content Type description change" display_field = "field1" field { @@ -145,7 +145,7 @@ resource "contentful_contenttype" "mycontenttype" { var testAccContentfulContentTypeLinkConfig = ` resource "contentful_contenttype" "mycontenttype" { space_id = "` + spaceID + `" - name = "TF Acc Test CT name change" + name = "tf_test1" description = "Terraform Acc Test Content Type description change" display_field = "field1" field { @@ -170,7 +170,7 @@ resource "contentful_contenttype" "mycontenttype" { resource "contentful_contenttype" "mylinked_contenttype" { space_id = "` + spaceID + `" - name = "TF Acc Test Linked CT" + name = "tf_linked" description = "Terraform Acc Test Content Type with links" display_field = "asset_field" field { diff --git a/contentful/resource_contentful_entry.go b/contentful/resource_contentful_entry.go new file mode 100644 index 0000000..fd35500 --- /dev/null +++ b/contentful/resource_contentful_entry.go @@ -0,0 +1,206 @@ +package contentful + +import ( + "github.com/hashicorp/terraform/helper/schema" + contentful "github.com/labd/contentful-go" +) + +func resourceContentfulEntry() *schema.Resource { + return &schema.Resource{ + Create: resourceCreateEntry, + Read: resourceReadEntry, + Update: resourceUpdateEntry, + Delete: resourceDeleteEntry, + + Schema: map[string]*schema.Schema{ + "entry_id": { + Type: schema.TypeString, + Required: true, + }, + "version": { + Type: schema.TypeInt, + Computed: true, + }, + "space_id": { + Type: schema.TypeString, + Required: true, + }, + "contenttype_id": { + Type: schema.TypeString, + Required: true, + }, + "locale": { + Type: schema.TypeString, + Required: true, + }, + "field": { + Type: schema.TypeList, + Required: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Required: true, + }, + "content": { + Type: schema.TypeString, + Required: true, + }, + "locale": { + Type: schema.TypeString, + Required: true, + }, + }, + }, + }, + "published": { + Type: schema.TypeBool, + Required: true, + }, + "archived": { + Type: schema.TypeBool, + Required: true, + }, + }, + } +} + +func resourceCreateEntry(d *schema.ResourceData, m interface{}) (err error) { + client := m.(*contentful.Client) + + fieldProperties := map[string]interface{}{} + rawField := d.Get("field").([]interface{}) + for i := 0; i < len(rawField); i++ { + field := rawField[i].(map[string]interface{}) + fieldProperties[field["id"].(string)] = map[string]interface{}{} + fieldProperties[field["id"].(string)].(map[string]interface{})[field["locale"].(string)] = field["content"].(string) + } + + entry := &contentful.Entry{ + Locale: d.Get("locale").(string), + Fields: fieldProperties, + Sys: &contentful.Sys{ + ID: d.Get("entry_id").(string), + }, + } + + err = client.Entries.Upsert(d.Get("space_id").(string), d.Get("contenttype_id").(string), entry) + if err != nil { + return err + } + + err = setEntryState(d, m) + if err != nil { + return err + } + + if err := setEntryProperties(d, entry); err != nil { + return err + } + + d.SetId(entry.Sys.ID) + return nil +} + +func resourceUpdateEntry(d *schema.ResourceData, m interface{}) (err error) { + client := m.(*contentful.Client) + spaceID := d.Get("space_id").(string) + entryID := d.Id() + + entry, err := client.Entries.Get(spaceID, entryID) + if err != nil { + return err + } + + fieldProperties := map[string]interface{}{} + rawField := d.Get("field").([]interface{}) + for i := 0; i < len(rawField); i++ { + field := rawField[i].(map[string]interface{}) + fieldProperties[field["id"].(string)] = map[string]interface{}{} + fieldProperties[field["id"].(string)].(map[string]interface{})[field["locale"].(string)] = field["content"].(string) + } + + entry.Fields = fieldProperties + entry.Locale = d.Get("locale").(string) + + err = client.Entries.Upsert(d.Get("space_id").(string), d.Get("contenttype_id").(string), entry) + if err != nil { + return err + } + + if err := setEntryState(d, m); err != nil { + return err + } + + if err := setEntryProperties(d, entry); err != nil { + return err + } + d.SetId(entry.Sys.ID) + + return nil +} + +func setEntryState(d *schema.ResourceData, m interface{}) (err error) { + client := m.(*contentful.Client) + spaceID := d.Get("space_id").(string) + entryID := d.Id() + + entry, _ := client.Entries.Get(spaceID, entryID) + + if d.Get("published").(bool) && entry.Sys.PublishedAt == "" { + err = client.Entries.Publish(spaceID, entry) + } else if d.Get("published").(bool) && entry.Sys.PublishedAt != "" { + err = client.Entries.Unpublish(spaceID, entry) + } + + if d.Get("archived").(bool) && entry.Sys.ArchivedAt == "" { + err = client.Entries.Publish(spaceID, entry) + } else if d.Get("archived").(bool) && entry.Sys.ArchivedAt != "" { + err = client.Entries.Unpublish(spaceID, entry) + } + + return nil +} + +func resourceReadEntry(d *schema.ResourceData, m interface{}) (err error) { + client := m.(*contentful.Client) + spaceID := d.Get("space_id").(string) + entryID := d.Id() + + entry, err := client.Entries.Get(spaceID, entryID) + if _, ok := err.(contentful.NotFoundError); ok { + d.SetId("") + return nil + } + + return setEntryProperties(d, entry) +} + +func resourceDeleteEntry(d *schema.ResourceData, m interface{}) (err error) { + client := m.(*contentful.Client) + spaceID := d.Get("space_id").(string) + entryID := d.Id() + + _, err = client.Entries.Get(spaceID, entryID) + if err != nil { + return err + } + + return client.Entries.Delete(spaceID, entryID) +} + +func setEntryProperties(d *schema.ResourceData, entry *contentful.Entry) error { + if err := d.Set("space_id", entry.Sys.Space.Sys.ID); err != nil { + return err + } + + if err := d.Set("version", entry.Sys.Version); err != nil { + return err + } + + if err := d.Set("contenttype_id", entry.Sys.ContentType.Sys.ID); err != nil { + return err + } + + return nil +} diff --git a/contentful/resource_contentful_entry_test.go b/contentful/resource_contentful_entry_test.go new file mode 100644 index 0000000..a98b796 --- /dev/null +++ b/contentful/resource_contentful_entry_test.go @@ -0,0 +1,207 @@ +package contentful + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + contentful "github.com/labd/contentful-go" +) + +func TestAccContentfulEntry_Basic(t *testing.T) { + var entry contentful.Entry + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccContentfulEntryDestroy, + Steps: []resource.TestStep{ + { + Config: testAccContentfulEntryConfig, + Check: resource.ComposeTestCheckFunc( + testAccCheckContentfulEntryExists("contentful_entry.myentry", &entry), + testAccCheckContentfulEntryAttributes(&entry, map[string]interface{}{ + "space_id": spaceID, + }), + ), + }, + { + Config: testAccContentfulEntryUpdateConfig, + Check: resource.ComposeTestCheckFunc( + testAccCheckContentfulEntryExists("contentful_entry.myentry", &entry), + testAccCheckContentfulEntryAttributes(&entry, map[string]interface{}{ + "space_id": spaceID, + }), + ), + }, + }, + }) +} + +func testAccCheckContentfulEntryExists(n string, entry *contentful.Entry) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("not Found: %s", n) + } + + spaceID := rs.Primary.Attributes["space_id"] + if spaceID == "" { + return fmt.Errorf("no space_id is set") + } + + contenttypeID := rs.Primary.Attributes["contenttype_id"] + if contenttypeID == "" { + return fmt.Errorf("no contenttype_id is set") + } + + client := testAccProvider.Meta().(*contentful.Client) + + contentfulEntry, err := client.Entries.Get(spaceID, rs.Primary.ID) + if err != nil { + return err + } + + *entry = *contentfulEntry + + return nil + } +} + +func testAccCheckContentfulEntryAttributes(entry *contentful.Entry, attrs map[string]interface{}) resource.TestCheckFunc { + return func(s *terraform.State) error { + + spaceIDCheck := attrs["space_id"].(string) + if entry.Sys.Space.Sys.ID != spaceIDCheck { + return fmt.Errorf("space id does not match: %s, %s", entry.Sys.Space.Sys.ID, spaceIDCheck) + } + + return nil + } +} + +func testAccContentfulEntryDestroy(s *terraform.State) error { + for _, rs := range s.RootModule().Resources { + if rs.Type != "contentful_entry" { + continue + } + + // get space id from resource data + spaceID := rs.Primary.Attributes["space_id"] + if spaceID == "" { + return fmt.Errorf("no space_id is set") + } + + // check webhook resource id + if rs.Primary.ID == "" { + return fmt.Errorf("no entry ID is set") + } + + // sdk client + client := testAccProvider.Meta().(*contentful.Client) + + entry, _ := client.Entries.Get(spaceID, rs.Primary.ID) + if entry == nil { + return nil + } + + return fmt.Errorf("entry still exists with id: %s", rs.Primary.ID) + } + + return nil +} + +var testAccContentfulEntryConfig = ` +resource "contentful_contenttype" "mycontenttype" { + space_id = "` + spaceID + `" + name = "tf_test_1" + description = "Terraform Acc Test Content Type" + display_field = "field1" + field { + disabled = false + id = "field1" + localized = false + name = "Field 1" + omitted = false + required = true + type = "Text" + } + field { + disabled = false + id = "field2" + localized = false + name = "Field 2" + omitted = false + required = true + type = "Text" + } +} + +resource "contentful_entry" "myentry" { + entry_id = "mytestentry" + space_id = "` + spaceID + `" + contenttype_id = "tf_test_1" + locale = "en-US" + field { + id = "field1" + content = "Hello, World!" + locale = "en-US" + } + field { + id = "field2" + content = "Bacon is healthy!" + locale = "en-US" + } + published = true + archived = false + depends_on = [contentful_contenttype.mycontenttype] +} +` + +var testAccContentfulEntryUpdateConfig = ` +resource "contentful_contenttype" "mycontenttype" { + space_id = "` + spaceID + `" + name = "tf_test_1" + description = "Terraform Acc Test Content Type" + display_field = "field1" + field { + disabled = false + id = "field1" + localized = false + name = "Field 1" + omitted = false + required = true + type = "Text" + } + field { + disabled = false + id = "field2" + localized = false + name = "Field 2" + omitted = false + required = true + type = "Text" + } +} + +resource "contentful_entry" "myentry" { + entry_id = "mytestentry" + space_id = "` + spaceID + `" + contenttype_id = "tf_test_1" + locale = "en-US" + field { + id = "field1" + content = "Hello, World!" + locale = "en-US" + } + field { + id = "field2" + content = "Bacon is healthy!" + locale = "en-US" + } + published = true + archived = false + depends_on = [contentful_contenttype.mycontenttype] +} +` diff --git a/go.mod b/go.mod index 574b785..c04fc29 100644 --- a/go.mod +++ b/go.mod @@ -4,5 +4,5 @@ go 1.14 require ( github.com/hashicorp/terraform v0.12.24 - github.com/labd/contentful-go v0.4.1-0.20200422125935-8ec49e6fa941 + github.com/labd/contentful-go v0.4.1-0.20200506145415-ef08d6413074 ) From c517c3f6cf4978714c13cfce3e82dcd2aa15dbd7 Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Fri, 8 May 2020 16:33:25 +0200 Subject: [PATCH 115/192] Added support for assets. Created the new assets resource. This resource is used to add files and images to the Contentful environment. --- contentful/provider.go | 1 + contentful/resource_contentful_asset.go | 344 +++++++++++++++++++ contentful/resource_contentful_asset_test.go | 158 +++++++++ contentful/resource_contentful_entry.go | 8 +- go.mod | 2 +- 5 files changed, 508 insertions(+), 5 deletions(-) create mode 100644 contentful/resource_contentful_asset.go create mode 100644 contentful/resource_contentful_asset_test.go diff --git a/contentful/provider.go b/contentful/provider.go index 19d95b9..e9e2224 100644 --- a/contentful/provider.go +++ b/contentful/provider.go @@ -31,6 +31,7 @@ func Provider() terraform.ResourceProvider { "contentful_locale": resourceContentfulLocale(), "contentful_environment": resourceContentfulEnvironment(), "contentful_entry": resourceContentfulEntry(), + "contentful_asset": resourceContentfulAsset(), }, ConfigureFunc: providerConfigure, } diff --git a/contentful/resource_contentful_asset.go b/contentful/resource_contentful_asset.go new file mode 100644 index 0000000..d03def7 --- /dev/null +++ b/contentful/resource_contentful_asset.go @@ -0,0 +1,344 @@ +package contentful + +import ( + "github.com/hashicorp/terraform/helper/schema" + contentful "github.com/labd/contentful-go" +) + +func resourceContentfulAsset() *schema.Resource { + return &schema.Resource{ + Create: resourceCreateAsset, + Read: resourceReadAsset, + Update: resourceUpdateAsset, + Delete: resourceDeleteAsset, + + Schema: map[string]*schema.Schema{ + "asset_id": { + Type: schema.TypeString, + Required: true, + }, + "version": { + Type: schema.TypeInt, + Computed: true, + }, + "locale": { + Type: schema.TypeString, + Required: true, + }, + "space_id": { + Type: schema.TypeString, + Required: true, + }, + "fields": { + Type: schema.TypeList, + Required: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "title": { + Type: schema.TypeList, + Required: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "content": { + Type: schema.TypeString, + Required: true, + }, + "locale": { + Type: schema.TypeString, + Required: true, + }, + }, + }, + }, + "description": { + Type: schema.TypeList, + Required: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "content": { + Type: schema.TypeString, + Required: true, + }, + "locale": { + Type: schema.TypeString, + Required: true, + }, + }, + }, + }, + "file": { + Type: schema.TypeMap, + Required: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "url": { + Type: schema.TypeString, + Optional: true, + }, + "upload": { + Type: schema.TypeString, + Optional: true, + }, + "details": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "size": { + Type: schema.TypeInt, + Required: true, + }, + "image": { + Type: schema.TypeSet, + Required: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "width": { + Type: schema.TypeInt, + Required: true, + }, + "height": { + Type: schema.TypeInt, + Required: true, + }, + }, + }, + }, + }, + }, + }, + "fileName": { + Type: schema.TypeString, + Required: true, + }, + "contentType": { + Type: schema.TypeString, + Required: true, + }, + }, + }, + }, + }, + }, + }, + "published": { + Type: schema.TypeBool, + Required: true, + }, + "archived": { + Type: schema.TypeBool, + Required: true, + }, + }, + } +} + +func resourceCreateAsset(d *schema.ResourceData, m interface{}) (err error) { + client := m.(*contentful.Client) + + fields := d.Get("fields").([]interface{})[0].(map[string]interface{}) + + localizedTitle := map[string]string{} + rawTitle := fields["title"].([]interface{}) + for i := 0; i < len(rawTitle); i++ { + field := rawTitle[i].(map[string]interface{}) + localizedTitle[field["locale"].(string)] = field["content"].(string) + } + + localizedDescription := map[string]string{} + rawDescription := fields["description"].([]interface{}) + for i := 0; i < len(rawDescription); i++ { + field := rawDescription[i].(map[string]interface{}) + localizedDescription[field["locale"].(string)] = field["content"].(string) + } + + file := fields["file"].(map[string]interface{}) + + asset := &contentful.Asset{ + Sys: &contentful.Sys{ + ID: d.Get("asset_id").(string), + Version: 0, + }, + Locale: d.Get("locale").(string), + Fields: &contentful.AssetFields{ + Title: localizedTitle, + Description: localizedDescription, + File: map[string]*contentful.File{ + d.Get("locale").(string): { + FileName: file["fileName"].(string), + ContentType: file["contentType"].(string), + UploadURL: file["upload"].(string), + }, + }, + }, + } + + if url, ok := file["url"].(string); ok { + asset.Fields.File[d.Get("locale").(string)].URL = url + } + + if details, ok := file["fileDetails"].(*contentful.FileDetails); ok { + asset.Fields.File[d.Get("locale").(string)].Details = details + } + + err = client.Assets.Upsert(d.Get("space_id").(string), asset) + if err != nil { + return err + } + + err = client.Assets.Process(d.Get("space_id").(string), asset) + if err != nil { + return err + } + + err = setAssetState(d, m) + if err != nil { + return err + } + + if err := setAssetProperties(d, asset); err != nil { + return err + } + + d.SetId(asset.Sys.ID) + return nil +} + +func resourceUpdateAsset(d *schema.ResourceData, m interface{}) (err error) { + client := m.(*contentful.Client) + spaceID := d.Get("space_id").(string) + assetID := d.Id() + + asset, err := client.Assets.Get(spaceID, assetID) + if err != nil { + return err + } + + fields := d.Get("fields").([]interface{})[0].(map[string]interface{}) + + localizedTitle := map[string]string{} + rawTitle := fields["title"].([]interface{}) + for i := 0; i < len(rawTitle); i++ { + field := rawTitle[i].(map[string]interface{}) + localizedTitle[field["locale"].(string)] = field["content"].(string) + } + + localizedDescription := map[string]string{} + rawDescription := fields["description"].([]interface{}) + for i := 0; i < len(rawDescription); i++ { + field := rawDescription[i].(map[string]interface{}) + localizedDescription[field["locale"].(string)] = field["content"].(string) + } + + file := fields["file"].(map[string]interface{}) + + asset = &contentful.Asset{ + Sys: &contentful.Sys{ + ID: d.Get("asset_id").(string), + Version: d.Get("version").(int), + }, + Locale: d.Get("locale").(string), + Fields: &contentful.AssetFields{ + Title: localizedTitle, + Description: localizedDescription, + File: map[string]*contentful.File{ + d.Get("locale").(string): { + FileName: file["fileName"].(string), + ContentType: file["contentType"].(string), + UploadURL: file["upload"].(string), + }, + }, + }, + } + + if url, ok := file["url"].(string); ok { + asset.Fields.File[d.Get("locale").(string)].URL = url + } + + if details, ok := file["fileDetails"].(*contentful.FileDetails); ok { + asset.Fields.File[d.Get("locale").(string)].Details = details + } + + err = client.Assets.Upsert(d.Get("space_id").(string), asset) + if err != nil { + return err + } + + err = client.Assets.Process(d.Get("space_id").(string), asset) + if err != nil { + return err + } + + err = setAssetState(d, m) + if err != nil { + return err + } + + if err := setAssetProperties(d, asset); err != nil { + return err + } + + d.SetId(asset.Sys.ID) + return nil +} + +func setAssetState(d *schema.ResourceData, m interface{}) (err error) { + client := m.(*contentful.Client) + spaceID := d.Get("space_id").(string) + assetID := d.Id() + + asset, _ := client.Assets.Get(spaceID, assetID) + + if d.Get("published").(bool) && asset.Sys.PublishedAt == "" { + err = client.Assets.Publish(spaceID, asset) + } else if !d.Get("published").(bool) && asset.Sys.PublishedAt != "" { + err = client.Assets.Unpublish(spaceID, asset) + } + + if d.Get("archived").(bool) && asset.Sys.ArchivedAt == "" { + err = client.Assets.Archive(spaceID, asset) + } else if !d.Get("archived").(bool) && asset.Sys.ArchivedAt != "" { + err = client.Assets.Unarchive(spaceID, asset) + } + + return nil +} + +func resourceReadAsset(d *schema.ResourceData, m interface{}) (err error) { + client := m.(*contentful.Client) + spaceID := d.Get("space_id").(string) + assetID := d.Id() + + asset, err := client.Assets.Get(spaceID, assetID) + if _, ok := err.(contentful.NotFoundError); ok { + d.SetId("") + return nil + } + + return setAssetProperties(d, asset) +} + +func resourceDeleteAsset(d *schema.ResourceData, m interface{}) (err error) { + client := m.(*contentful.Client) + spaceID := d.Get("space_id").(string) + assetID := d.Id() + + asset, err := client.Assets.Get(spaceID, assetID) + if err != nil { + return err + } + + return client.Assets.Delete(spaceID, asset) +} + +func setAssetProperties(d *schema.ResourceData, asset *contentful.Asset) error { + if err := d.Set("space_id", asset.Sys.Space.Sys.ID); err != nil { + return err + } + + if err := d.Set("version", asset.Sys.Version); err != nil { + return err + } + + return nil +} diff --git a/contentful/resource_contentful_asset_test.go b/contentful/resource_contentful_asset_test.go new file mode 100644 index 0000000..576e75c --- /dev/null +++ b/contentful/resource_contentful_asset_test.go @@ -0,0 +1,158 @@ +package contentful + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + contentful "github.com/labd/contentful-go" +) + +func TestAccContentfulAsset_Basic(t *testing.T) { + var asset contentful.Asset + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccContentfulAssetDestroy, + Steps: []resource.TestStep{ + { + Config: testAccContentfulAssetConfig, + Check: resource.ComposeTestCheckFunc( + testAccCheckContentfulAssetExists("contentful_asset.myasset", &asset), + testAccCheckContentfulAssetAttributes(&asset, map[string]interface{}{ + "space_id": spaceID, + }), + ), + }, + { + Config: testAccContentfulAssetUpdateConfig, + Check: resource.ComposeTestCheckFunc( + testAccCheckContentfulAssetExists("contentful_asset.myasset", &asset), + testAccCheckContentfulAssetAttributes(&asset, map[string]interface{}{ + "space_id": spaceID, + }), + ), + }, + }, + }) +} + +func testAccCheckContentfulAssetExists(n string, asset *contentful.Asset) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("not Found: %s", n) + } + + spaceID := rs.Primary.Attributes["space_id"] + if spaceID == "" { + return fmt.Errorf("no space_id is set") + } + + client := testAccProvider.Meta().(*contentful.Client) + + contentfulAsset, err := client.Assets.Get(spaceID, rs.Primary.ID) + if err != nil { + return err + } + + *asset = *contentfulAsset + + return nil + } +} + +func testAccCheckContentfulAssetAttributes(asset *contentful.Asset, attrs map[string]interface{}) resource.TestCheckFunc { + return func(s *terraform.State) error { + + spaceIDCheck := attrs["space_id"].(string) + if asset.Sys.Space.Sys.ID != spaceIDCheck { + return fmt.Errorf("space id does not match: %s, %s", asset.Sys.Space.Sys.ID, spaceIDCheck) + } + + return nil + } +} + +func testAccContentfulAssetDestroy(s *terraform.State) error { + for _, rs := range s.RootModule().Resources { + if rs.Type != "contentful_entry" { + continue + } + + // get space id from resource data + spaceID := rs.Primary.Attributes["space_id"] + if spaceID == "" { + return fmt.Errorf("no space_id is set") + } + + // check webhook resource id + if rs.Primary.ID == "" { + return fmt.Errorf("no asset ID is set") + } + + // sdk client + client := testAccProvider.Meta().(*contentful.Client) + + asset, _ := client.Assets.Get(spaceID, rs.Primary.ID) + if asset == nil { + return nil + } + + return fmt.Errorf("asset still exists with id: %s", rs.Primary.ID) + } + + return nil +} + +var testAccContentfulAssetConfig = ` +resource "contentful_asset" "myasset" { + asset_id = "test_asset" + locale = "en-US" + space_id = "` + spaceID + `" + fields { + title { + locale = "en-US" + content = "Asset title" + } + description { + locale = "en-US" + content = "Asset description" + } + file = { + upload = "https://images.ctfassets.net/fo9twyrwpveg/2VQx7vz73aMEYi20MMgCk0/66e502115b1f1f973a944b4bd2cc536f/IC-1H_Modern_Stack_Website.svg" + fileName = "example.jpeg" + contentType = "image/jpeg" + } + } + published = true + archived = false +} +` + +var testAccContentfulAssetUpdateConfig = ` +resource "contentful_asset" "myasset" { + asset_id = "test_asset" + locale = "en-US" + space_id = "` + spaceID + `" + fields { + title { + locale = "en-US" + content = "Updated asset title" + } + description { + locale = "en-US" + content = "Updated asset description" + } + file = { + upload = "https://images.ctfassets.net/fo9twyrwpveg/2VQx7vz73aMEYi20MMgCk0/66e502115b1f1f973a944b4bd2cc536f/IC-1H_Modern_Stack_Website.svg" + fileName = "example.jpeg" + contentType = "image/jpeg" + } + } + published = true + archived = false +} +` diff --git a/contentful/resource_contentful_entry.go b/contentful/resource_contentful_entry.go index fd35500..baa3105 100644 --- a/contentful/resource_contentful_entry.go +++ b/contentful/resource_contentful_entry.go @@ -149,14 +149,14 @@ func setEntryState(d *schema.ResourceData, m interface{}) (err error) { if d.Get("published").(bool) && entry.Sys.PublishedAt == "" { err = client.Entries.Publish(spaceID, entry) - } else if d.Get("published").(bool) && entry.Sys.PublishedAt != "" { + } else if !d.Get("published").(bool) && entry.Sys.PublishedAt != "" { err = client.Entries.Unpublish(spaceID, entry) } if d.Get("archived").(bool) && entry.Sys.ArchivedAt == "" { - err = client.Entries.Publish(spaceID, entry) - } else if d.Get("archived").(bool) && entry.Sys.ArchivedAt != "" { - err = client.Entries.Unpublish(spaceID, entry) + err = client.Entries.Archive(spaceID, entry) + } else if !d.Get("archived").(bool) && entry.Sys.ArchivedAt != "" { + err = client.Entries.Unarchive(spaceID, entry) } return nil diff --git a/go.mod b/go.mod index c04fc29..0e73d39 100644 --- a/go.mod +++ b/go.mod @@ -4,5 +4,5 @@ go 1.14 require ( github.com/hashicorp/terraform v0.12.24 - github.com/labd/contentful-go v0.4.1-0.20200506145415-ef08d6413074 + github.com/labd/contentful-go v0.4.1-0.20200508125900-edd2d77b81af ) From 78b3b44e639a340be5f163c65a825608a5c2f5f6 Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Mon, 11 May 2020 11:17:51 +0200 Subject: [PATCH 116/192] Fixed versioning bug. When creating and updating assets and entries, the publish and unpublish calls also updates the version property. This resulted in a version mismatch error. --- README.md | 3 +- contentful/resource_contentful_asset.go | 41 ++++++++++++-------- contentful/resource_contentful_asset_test.go | 2 +- contentful/resource_contentful_entry.go | 31 ++++++++------- contentful/resource_contentful_entry_test.go | 2 +- 5 files changed, 45 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index 89d9180..a8b9bdf 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,8 @@ Create, update and delete Contentful resources such as: - [x] Webhooks - [x] Locales - [x] Environments -- [ ] Organizations +- [x] Entries +- [x] Assets # Getting started diff --git a/contentful/resource_contentful_asset.go b/contentful/resource_contentful_asset.go index d03def7..71e57e4 100644 --- a/contentful/resource_contentful_asset.go +++ b/contentful/resource_contentful_asset.go @@ -167,7 +167,6 @@ func resourceCreateAsset(d *schema.ResourceData, m interface{}) (err error) { d.Get("locale").(string): { FileName: file["fileName"].(string), ContentType: file["contentType"].(string), - UploadURL: file["upload"].(string), }, }, }, @@ -177,6 +176,10 @@ func resourceCreateAsset(d *schema.ResourceData, m interface{}) (err error) { asset.Fields.File[d.Get("locale").(string)].URL = url } + if upload, ok := file["upload"].(string); ok { + asset.Fields.File[d.Get("locale").(string)].UploadURL = upload + } + if details, ok := file["fileDetails"].(*contentful.FileDetails); ok { asset.Fields.File[d.Get("locale").(string)].Details = details } @@ -191,17 +194,18 @@ func resourceCreateAsset(d *schema.ResourceData, m interface{}) (err error) { return err } - err = setAssetState(d, m) - if err != nil { + d.SetId(asset.Sys.ID) + + if err := setAssetProperties(d, asset); err != nil { return err } - if err := setAssetProperties(d, asset); err != nil { + err = setAssetState(d, m) + if err != nil { return err } - d.SetId(asset.Sys.ID) - return nil + return err } func resourceUpdateAsset(d *schema.ResourceData, m interface{}) (err error) { @@ -269,17 +273,18 @@ func resourceUpdateAsset(d *schema.ResourceData, m interface{}) (err error) { return err } - err = setAssetState(d, m) - if err != nil { + d.SetId(asset.Sys.ID) + + if err := setAssetProperties(d, asset); err != nil { return err } - if err := setAssetProperties(d, asset); err != nil { + err = setAssetState(d, m) + if err != nil { return err } - d.SetId(asset.Sys.ID) - return nil + return err } func setAssetState(d *schema.ResourceData, m interface{}) (err error) { @@ -301,7 +306,11 @@ func setAssetState(d *schema.ResourceData, m interface{}) (err error) { err = client.Assets.Unarchive(spaceID, asset) } - return nil + if err := setAssetProperties(d, asset); err != nil { + return err + } + + return err } func resourceReadAsset(d *schema.ResourceData, m interface{}) (err error) { @@ -331,14 +340,14 @@ func resourceDeleteAsset(d *schema.ResourceData, m interface{}) (err error) { return client.Assets.Delete(spaceID, asset) } -func setAssetProperties(d *schema.ResourceData, asset *contentful.Asset) error { - if err := d.Set("space_id", asset.Sys.Space.Sys.ID); err != nil { +func setAssetProperties(d *schema.ResourceData, asset *contentful.Asset) (err error) { + if err = d.Set("space_id", asset.Sys.Space.Sys.ID); err != nil { return err } - if err := d.Set("version", asset.Sys.Version); err != nil { + if err = d.Set("version", asset.Sys.Version); err != nil { return err } - return nil + return err } diff --git a/contentful/resource_contentful_asset_test.go b/contentful/resource_contentful_asset_test.go index 576e75c..b198af3 100644 --- a/contentful/resource_contentful_asset_test.go +++ b/contentful/resource_contentful_asset_test.go @@ -152,7 +152,7 @@ resource "contentful_asset" "myasset" { contentType = "image/jpeg" } } - published = true + published = false archived = false } ` diff --git a/contentful/resource_contentful_entry.go b/contentful/resource_contentful_entry.go index baa3105..7c1e109 100644 --- a/contentful/resource_contentful_entry.go +++ b/contentful/resource_contentful_entry.go @@ -89,17 +89,17 @@ func resourceCreateEntry(d *schema.ResourceData, m interface{}) (err error) { return err } - err = setEntryState(d, m) - if err != nil { + if err := setEntryProperties(d, entry); err != nil { return err } - if err := setEntryProperties(d, entry); err != nil { + d.SetId(entry.Sys.ID) + + if err := setEntryState(d, m); err != nil { return err } - d.SetId(entry.Sys.ID) - return nil + return err } func resourceUpdateEntry(d *schema.ResourceData, m interface{}) (err error) { @@ -128,16 +128,17 @@ func resourceUpdateEntry(d *schema.ResourceData, m interface{}) (err error) { return err } - if err := setEntryState(d, m); err != nil { + d.SetId(entry.Sys.ID) + + if err := setEntryProperties(d, entry); err != nil { return err } - if err := setEntryProperties(d, entry); err != nil { + if err := setEntryState(d, m); err != nil { return err } - d.SetId(entry.Sys.ID) - return nil + return err } func setEntryState(d *schema.ResourceData, m interface{}) (err error) { @@ -159,7 +160,7 @@ func setEntryState(d *schema.ResourceData, m interface{}) (err error) { err = client.Entries.Unarchive(spaceID, entry) } - return nil + return err } func resourceReadEntry(d *schema.ResourceData, m interface{}) (err error) { @@ -189,18 +190,18 @@ func resourceDeleteEntry(d *schema.ResourceData, m interface{}) (err error) { return client.Entries.Delete(spaceID, entryID) } -func setEntryProperties(d *schema.ResourceData, entry *contentful.Entry) error { - if err := d.Set("space_id", entry.Sys.Space.Sys.ID); err != nil { +func setEntryProperties(d *schema.ResourceData, entry *contentful.Entry) (err error) { + if err = d.Set("space_id", entry.Sys.Space.Sys.ID); err != nil { return err } - if err := d.Set("version", entry.Sys.Version); err != nil { + if err = d.Set("version", entry.Sys.Version); err != nil { return err } - if err := d.Set("contenttype_id", entry.Sys.ContentType.Sys.ID); err != nil { + if err = d.Set("contenttype_id", entry.Sys.ContentType.Sys.ID); err != nil { return err } - return nil + return err } diff --git a/contentful/resource_contentful_entry_test.go b/contentful/resource_contentful_entry_test.go index a98b796..6c589a7 100644 --- a/contentful/resource_contentful_entry_test.go +++ b/contentful/resource_contentful_entry_test.go @@ -200,7 +200,7 @@ resource "contentful_entry" "myentry" { content = "Bacon is healthy!" locale = "en-US" } - published = true + published = false archived = false depends_on = [contentful_contenttype.mycontenttype] } From 8ab4baef29486d76d0176cac3f76027b56003024 Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Mon, 11 May 2020 11:46:03 +0200 Subject: [PATCH 117/192] Fixed early-return bug. Setting properties call seems to throw an error when called with Docker. Removed return should fix this problem. --- contentful/resource_contentful_asset.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/contentful/resource_contentful_asset.go b/contentful/resource_contentful_asset.go index 71e57e4..af34fd9 100644 --- a/contentful/resource_contentful_asset.go +++ b/contentful/resource_contentful_asset.go @@ -306,9 +306,7 @@ func setAssetState(d *schema.ResourceData, m interface{}) (err error) { err = client.Assets.Unarchive(spaceID, asset) } - if err := setAssetProperties(d, asset); err != nil { - return err - } + err = setAssetProperties(d, asset) return err } From 72332a013c8a1dac3a95c9774288480d226ddd24 Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Wed, 13 May 2020 10:49:01 +0200 Subject: [PATCH 118/192] Fixed optional fields of asset. Update was missing optional fields, also added field uploadFrom. This is required for uploads --- contentful/resource_contentful_asset.go | 19 +++++++++++++++++-- go.mod | 2 +- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/contentful/resource_contentful_asset.go b/contentful/resource_contentful_asset.go index af34fd9..d48036a 100644 --- a/contentful/resource_contentful_asset.go +++ b/contentful/resource_contentful_asset.go @@ -107,9 +107,13 @@ func resourceContentfulAsset() *schema.Resource { }, }, }, + "uploadFrom": { + Type: schema.TypeString, + Computed: true, + }, "fileName": { Type: schema.TypeString, - Required: true, + Computed: true, }, "contentType": { Type: schema.TypeString, @@ -184,6 +188,10 @@ func resourceCreateAsset(d *schema.ResourceData, m interface{}) (err error) { asset.Fields.File[d.Get("locale").(string)].Details = details } + if uploadFrom, ok := file["uploadFrom"].(string); ok { + asset.Fields.File[d.Get("locale").(string)].UploadFrom.Sys.ID = uploadFrom + } + err = client.Assets.Upsert(d.Get("space_id").(string), asset) if err != nil { return err @@ -249,7 +257,6 @@ func resourceUpdateAsset(d *schema.ResourceData, m interface{}) (err error) { d.Get("locale").(string): { FileName: file["fileName"].(string), ContentType: file["contentType"].(string), - UploadURL: file["upload"].(string), }, }, }, @@ -259,10 +266,18 @@ func resourceUpdateAsset(d *schema.ResourceData, m interface{}) (err error) { asset.Fields.File[d.Get("locale").(string)].URL = url } + if upload, ok := file["upload"].(string); ok { + asset.Fields.File[d.Get("locale").(string)].UploadURL = upload + } + if details, ok := file["fileDetails"].(*contentful.FileDetails); ok { asset.Fields.File[d.Get("locale").(string)].Details = details } + if uploadFrom, ok := file["uploadFrom"].(string); ok { + asset.Fields.File[d.Get("locale").(string)].UploadFrom.Sys.ID = uploadFrom + } + err = client.Assets.Upsert(d.Get("space_id").(string), asset) if err != nil { return err diff --git a/go.mod b/go.mod index 0e73d39..a01d7c9 100644 --- a/go.mod +++ b/go.mod @@ -4,5 +4,5 @@ go 1.14 require ( github.com/hashicorp/terraform v0.12.24 - github.com/labd/contentful-go v0.4.1-0.20200508125900-edd2d77b81af + github.com/labd/contentful-go v0.4.1-0.20200512094354-cc45b8138ed9 ) From 8726ad74a84d4f206f7472c71fcd2bd1051a6ae1 Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Wed, 13 May 2020 10:50:40 +0200 Subject: [PATCH 119/192] Added uploads service. Uploads can be used to set local files to the Contentful environment. --- contentful/provider.go | 1 + contentful/resource_contentful_upload.go | 148 ++++++++++++++++++ contentful/resource_contentful_upload_test.go | 110 +++++++++++++ 3 files changed, 259 insertions(+) create mode 100644 contentful/resource_contentful_upload.go create mode 100644 contentful/resource_contentful_upload_test.go diff --git a/contentful/provider.go b/contentful/provider.go index e9e2224..f357e24 100644 --- a/contentful/provider.go +++ b/contentful/provider.go @@ -32,6 +32,7 @@ func Provider() terraform.ResourceProvider { "contentful_environment": resourceContentfulEnvironment(), "contentful_entry": resourceContentfulEntry(), "contentful_asset": resourceContentfulAsset(), + "contentful_upload": resourceContentfulUpload(), }, ConfigureFunc: providerConfigure, } diff --git a/contentful/resource_contentful_upload.go b/contentful/resource_contentful_upload.go new file mode 100644 index 0000000..fceb740 --- /dev/null +++ b/contentful/resource_contentful_upload.go @@ -0,0 +1,148 @@ +package contentful + +import ( + "encoding/json" + "fmt" + "github.com/hashicorp/terraform/helper/schema" + contentful "github.com/labd/contentful-go" +) + +func resourceContentfulUpload() *schema.Resource { + return &schema.Resource{ + Create: resourceCreateUpload, + Read: resourceReadUpload, + Update: nil, + Delete: resourceDeleteUpload, + + Schema: map[string]*schema.Schema{ + "space_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "file_path": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "asset_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "locale": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "title": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "description": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + }, + } +} + +func resourceCreateUpload(d *schema.ResourceData, m interface{}) (err error) { + uploadClient := contentful.NewResourceClient(CMAToken) + uploadClient.SetOrganization(orgID) + client := m.(*contentful.Client) + + upload := contentful.Resource{} + + fmt.Println(d.Get("space_id").(string)) + fmt.Println(d.Get("file_path").(string)) + + response := uploadClient.Resources.Create(d.Get("space_id").(string), d.Get("file_path").(string)) + err = json.Unmarshal([]byte(response.Error()), &upload) + + d.SetId(upload.Sys.ID) + + if err := setUploadProperties(d, &upload); err != nil { + return err + } + + asset := &contentful.Asset{ + Sys: &contentful.Sys{ + ID: d.Get("asset_id").(string), + Version: 0, + }, + Locale: d.Get("locale").(string), + Fields: &contentful.AssetFields{ + Title: map[string]string{ + d.Get("locale").(string): d.Get("title").(string), + }, + Description: map[string]string{ + d.Get("locale").(string): d.Get("description").(string), + }, + File: map[string]*contentful.File{ + d.Get("locale").(string): { + UploadFrom: &contentful.UploadFrom{ + Sys: &contentful.Sys{ + ID: "upload.Sys.ID", + LinkType: "Upload", + }, + }, + }, + }, + }, + } + + err = client.Assets.Upsert(d.Get("space_id").(string), asset) + if err != nil { + return err + } + + err = client.Assets.Process(d.Get("space_id").(string), asset) + if err != nil { + return err + } + + err = client.Assets.Publish(spaceID, asset) + if err != nil { + return err + } + + return err +} + +func resourceReadUpload(d *schema.ResourceData, m interface{}) (err error) { + client := m.(*contentful.Client) + spaceID := d.Get("space_id").(string) + uploadID := d.Id() + + upload, err := client.Resources.Get(spaceID, uploadID) + if _, ok := err.(contentful.NotFoundError); ok { + d.SetId("") + return err + } + + return setUploadProperties(d, upload) +} + +func resourceDeleteUpload(d *schema.ResourceData, m interface{}) (err error) { + client := m.(*contentful.Client) + spaceID := d.Get("space_id").(string) + uploadID := d.Id() + + _, err = client.Resources.Get(spaceID, uploadID) + if err != nil { + return err + } + + return client.Resources.Delete(spaceID, uploadID) +} + +func setUploadProperties(d *schema.ResourceData, resource *contentful.Resource) (err error) { + if err = d.Set("space_id", resource.Sys.Space.Sys.ID); err != nil { + return err + } + + return err +} diff --git a/contentful/resource_contentful_upload_test.go b/contentful/resource_contentful_upload_test.go new file mode 100644 index 0000000..047e71a --- /dev/null +++ b/contentful/resource_contentful_upload_test.go @@ -0,0 +1,110 @@ +package contentful + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + contentful "github.com/labd/contentful-go" +) + +func TestAccContentfulUpload_Basic(t *testing.T) { + var upload contentful.Resource + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccContentfulUploadDestroy, + Steps: []resource.TestStep{ + { + Config: testAccContentfulUploadConfig, + Check: resource.ComposeTestCheckFunc( + testAccCheckContentfulUploadExists("contentful_asset.myupload", &upload), + testAccCheckContentfulUploadAttributes(&upload, map[string]interface{}{ + "space_id": spaceID, + }), + ), + }, + }, + }) +} + +func testAccCheckContentfulUploadExists(n string, upload *contentful.Resource) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("not Found: %s", n) + } + + spaceID := rs.Primary.Attributes["space_id"] + if spaceID == "" { + return fmt.Errorf("no space_id is set") + } + + client := testAccProvider.Meta().(*contentful.Client) + + contentfulAsset, err := client.Resources.Get(spaceID, rs.Primary.ID) + if err != nil { + return err + } + + *upload = *contentfulAsset + + return nil + } +} + +func testAccCheckContentfulUploadAttributes(upload *contentful.Resource, attrs map[string]interface{}) resource.TestCheckFunc { + return func(s *terraform.State) error { + + spaceIDCheck := attrs["space_id"].(string) + if upload.Sys.Space.Sys.ID != spaceIDCheck { + return fmt.Errorf("space id does not match: %s, %s", upload.Sys.Space.Sys.ID, spaceIDCheck) + } + + return nil + } +} + +func testAccContentfulUploadDestroy(s *terraform.State) error { + for _, rs := range s.RootModule().Resources { + if rs.Type != "contentful_entry" { + continue + } + + // get space id from resource data + spaceID := rs.Primary.Attributes["space_id"] + if spaceID == "" { + return fmt.Errorf("no space_id is set") + } + + // check webhook resource id + if rs.Primary.ID == "" { + return fmt.Errorf("no asset ID is set") + } + + // sdk client + client := testAccProvider.Meta().(*contentful.Client) + + asset, _ := client.Assets.Get(spaceID, rs.Primary.ID) + if asset == nil { + return nil + } + + return fmt.Errorf("asset still exists with id: %s", rs.Primary.ID) + } + + return nil +} + +var testAccContentfulUploadConfig = ` +resource "contentful_upload" "myupload" { + space_id = "` + spaceID + `" + file_path = "/home/kantoor/go/src/github.com/labd/terraform-contentful/local/upload_test.png" + asset_id = "upload_test" + locale = "en-US" + title = "This is an asset" + description = "Uploaded asset!" +} +` From 83901b5f20990738493e45fcbeeca8883dedd2e6 Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Mon, 11 May 2020 12:39:28 +0200 Subject: [PATCH 120/192] Features/assets (#6) * Added support for assets. Created the new assets resource. This resource is used to add files and images to the Contentful environment. * Fixed versioning bug. When creating and updating assets and entries, the publish and unpublish calls also updates the version property. This resulted in a version mismatch error. * Fixed early-return bug. Setting properties call seems to throw an error when called with Docker. Removed return should fix this problem. Co-authored-by: Kantoor --- contentful/provider.go | 1 - contentful/resource_contentful_asset.go | 19 ++----------------- go.mod | 2 +- 3 files changed, 3 insertions(+), 19 deletions(-) diff --git a/contentful/provider.go b/contentful/provider.go index f357e24..e9e2224 100644 --- a/contentful/provider.go +++ b/contentful/provider.go @@ -32,7 +32,6 @@ func Provider() terraform.ResourceProvider { "contentful_environment": resourceContentfulEnvironment(), "contentful_entry": resourceContentfulEntry(), "contentful_asset": resourceContentfulAsset(), - "contentful_upload": resourceContentfulUpload(), }, ConfigureFunc: providerConfigure, } diff --git a/contentful/resource_contentful_asset.go b/contentful/resource_contentful_asset.go index d48036a..af34fd9 100644 --- a/contentful/resource_contentful_asset.go +++ b/contentful/resource_contentful_asset.go @@ -107,13 +107,9 @@ func resourceContentfulAsset() *schema.Resource { }, }, }, - "uploadFrom": { - Type: schema.TypeString, - Computed: true, - }, "fileName": { Type: schema.TypeString, - Computed: true, + Required: true, }, "contentType": { Type: schema.TypeString, @@ -188,10 +184,6 @@ func resourceCreateAsset(d *schema.ResourceData, m interface{}) (err error) { asset.Fields.File[d.Get("locale").(string)].Details = details } - if uploadFrom, ok := file["uploadFrom"].(string); ok { - asset.Fields.File[d.Get("locale").(string)].UploadFrom.Sys.ID = uploadFrom - } - err = client.Assets.Upsert(d.Get("space_id").(string), asset) if err != nil { return err @@ -257,6 +249,7 @@ func resourceUpdateAsset(d *schema.ResourceData, m interface{}) (err error) { d.Get("locale").(string): { FileName: file["fileName"].(string), ContentType: file["contentType"].(string), + UploadURL: file["upload"].(string), }, }, }, @@ -266,18 +259,10 @@ func resourceUpdateAsset(d *schema.ResourceData, m interface{}) (err error) { asset.Fields.File[d.Get("locale").(string)].URL = url } - if upload, ok := file["upload"].(string); ok { - asset.Fields.File[d.Get("locale").(string)].UploadURL = upload - } - if details, ok := file["fileDetails"].(*contentful.FileDetails); ok { asset.Fields.File[d.Get("locale").(string)].Details = details } - if uploadFrom, ok := file["uploadFrom"].(string); ok { - asset.Fields.File[d.Get("locale").(string)].UploadFrom.Sys.ID = uploadFrom - } - err = client.Assets.Upsert(d.Get("space_id").(string), asset) if err != nil { return err diff --git a/go.mod b/go.mod index a01d7c9..0e73d39 100644 --- a/go.mod +++ b/go.mod @@ -4,5 +4,5 @@ go 1.14 require ( github.com/hashicorp/terraform v0.12.24 - github.com/labd/contentful-go v0.4.1-0.20200512094354-cc45b8138ed9 + github.com/labd/contentful-go v0.4.1-0.20200508125900-edd2d77b81af ) From 4466f08f05e5f36c3aacb132b7e4d7cd9f0156cf Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Wed, 13 May 2020 11:00:09 +0200 Subject: [PATCH 121/192] Optional fields Added missing optional fields and the uploadFrom field which is required by the upload resource. --- contentful/resource_contentful_asset.go | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/contentful/resource_contentful_asset.go b/contentful/resource_contentful_asset.go index af34fd9..d48036a 100644 --- a/contentful/resource_contentful_asset.go +++ b/contentful/resource_contentful_asset.go @@ -107,9 +107,13 @@ func resourceContentfulAsset() *schema.Resource { }, }, }, + "uploadFrom": { + Type: schema.TypeString, + Computed: true, + }, "fileName": { Type: schema.TypeString, - Required: true, + Computed: true, }, "contentType": { Type: schema.TypeString, @@ -184,6 +188,10 @@ func resourceCreateAsset(d *schema.ResourceData, m interface{}) (err error) { asset.Fields.File[d.Get("locale").(string)].Details = details } + if uploadFrom, ok := file["uploadFrom"].(string); ok { + asset.Fields.File[d.Get("locale").(string)].UploadFrom.Sys.ID = uploadFrom + } + err = client.Assets.Upsert(d.Get("space_id").(string), asset) if err != nil { return err @@ -249,7 +257,6 @@ func resourceUpdateAsset(d *schema.ResourceData, m interface{}) (err error) { d.Get("locale").(string): { FileName: file["fileName"].(string), ContentType: file["contentType"].(string), - UploadURL: file["upload"].(string), }, }, }, @@ -259,10 +266,18 @@ func resourceUpdateAsset(d *schema.ResourceData, m interface{}) (err error) { asset.Fields.File[d.Get("locale").(string)].URL = url } + if upload, ok := file["upload"].(string); ok { + asset.Fields.File[d.Get("locale").(string)].UploadURL = upload + } + if details, ok := file["fileDetails"].(*contentful.FileDetails); ok { asset.Fields.File[d.Get("locale").(string)].Details = details } + if uploadFrom, ok := file["uploadFrom"].(string); ok { + asset.Fields.File[d.Get("locale").(string)].UploadFrom.Sys.ID = uploadFrom + } + err = client.Assets.Upsert(d.Get("space_id").(string), asset) if err != nil { return err From 352daa062dfab739e86437971f5cb8a8ef10f976 Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Wed, 13 May 2020 11:02:12 +0200 Subject: [PATCH 122/192] Uploads resource to different branch. --- contentful/resource_contentful_upload.go | 148 ------------------ contentful/resource_contentful_upload_test.go | 110 ------------- 2 files changed, 258 deletions(-) delete mode 100644 contentful/resource_contentful_upload.go delete mode 100644 contentful/resource_contentful_upload_test.go diff --git a/contentful/resource_contentful_upload.go b/contentful/resource_contentful_upload.go deleted file mode 100644 index fceb740..0000000 --- a/contentful/resource_contentful_upload.go +++ /dev/null @@ -1,148 +0,0 @@ -package contentful - -import ( - "encoding/json" - "fmt" - "github.com/hashicorp/terraform/helper/schema" - contentful "github.com/labd/contentful-go" -) - -func resourceContentfulUpload() *schema.Resource { - return &schema.Resource{ - Create: resourceCreateUpload, - Read: resourceReadUpload, - Update: nil, - Delete: resourceDeleteUpload, - - Schema: map[string]*schema.Schema{ - "space_id": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - }, - "file_path": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - }, - "asset_id": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - }, - "locale": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - }, - "title": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - }, - "description": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - }, - }, - } -} - -func resourceCreateUpload(d *schema.ResourceData, m interface{}) (err error) { - uploadClient := contentful.NewResourceClient(CMAToken) - uploadClient.SetOrganization(orgID) - client := m.(*contentful.Client) - - upload := contentful.Resource{} - - fmt.Println(d.Get("space_id").(string)) - fmt.Println(d.Get("file_path").(string)) - - response := uploadClient.Resources.Create(d.Get("space_id").(string), d.Get("file_path").(string)) - err = json.Unmarshal([]byte(response.Error()), &upload) - - d.SetId(upload.Sys.ID) - - if err := setUploadProperties(d, &upload); err != nil { - return err - } - - asset := &contentful.Asset{ - Sys: &contentful.Sys{ - ID: d.Get("asset_id").(string), - Version: 0, - }, - Locale: d.Get("locale").(string), - Fields: &contentful.AssetFields{ - Title: map[string]string{ - d.Get("locale").(string): d.Get("title").(string), - }, - Description: map[string]string{ - d.Get("locale").(string): d.Get("description").(string), - }, - File: map[string]*contentful.File{ - d.Get("locale").(string): { - UploadFrom: &contentful.UploadFrom{ - Sys: &contentful.Sys{ - ID: "upload.Sys.ID", - LinkType: "Upload", - }, - }, - }, - }, - }, - } - - err = client.Assets.Upsert(d.Get("space_id").(string), asset) - if err != nil { - return err - } - - err = client.Assets.Process(d.Get("space_id").(string), asset) - if err != nil { - return err - } - - err = client.Assets.Publish(spaceID, asset) - if err != nil { - return err - } - - return err -} - -func resourceReadUpload(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Client) - spaceID := d.Get("space_id").(string) - uploadID := d.Id() - - upload, err := client.Resources.Get(spaceID, uploadID) - if _, ok := err.(contentful.NotFoundError); ok { - d.SetId("") - return err - } - - return setUploadProperties(d, upload) -} - -func resourceDeleteUpload(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Client) - spaceID := d.Get("space_id").(string) - uploadID := d.Id() - - _, err = client.Resources.Get(spaceID, uploadID) - if err != nil { - return err - } - - return client.Resources.Delete(spaceID, uploadID) -} - -func setUploadProperties(d *schema.ResourceData, resource *contentful.Resource) (err error) { - if err = d.Set("space_id", resource.Sys.Space.Sys.ID); err != nil { - return err - } - - return err -} diff --git a/contentful/resource_contentful_upload_test.go b/contentful/resource_contentful_upload_test.go deleted file mode 100644 index 047e71a..0000000 --- a/contentful/resource_contentful_upload_test.go +++ /dev/null @@ -1,110 +0,0 @@ -package contentful - -import ( - "fmt" - "testing" - - "github.com/hashicorp/terraform/helper/resource" - "github.com/hashicorp/terraform/terraform" - contentful "github.com/labd/contentful-go" -) - -func TestAccContentfulUpload_Basic(t *testing.T) { - var upload contentful.Resource - - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccContentfulUploadDestroy, - Steps: []resource.TestStep{ - { - Config: testAccContentfulUploadConfig, - Check: resource.ComposeTestCheckFunc( - testAccCheckContentfulUploadExists("contentful_asset.myupload", &upload), - testAccCheckContentfulUploadAttributes(&upload, map[string]interface{}{ - "space_id": spaceID, - }), - ), - }, - }, - }) -} - -func testAccCheckContentfulUploadExists(n string, upload *contentful.Resource) resource.TestCheckFunc { - return func(s *terraform.State) error { - rs, ok := s.RootModule().Resources[n] - if !ok { - return fmt.Errorf("not Found: %s", n) - } - - spaceID := rs.Primary.Attributes["space_id"] - if spaceID == "" { - return fmt.Errorf("no space_id is set") - } - - client := testAccProvider.Meta().(*contentful.Client) - - contentfulAsset, err := client.Resources.Get(spaceID, rs.Primary.ID) - if err != nil { - return err - } - - *upload = *contentfulAsset - - return nil - } -} - -func testAccCheckContentfulUploadAttributes(upload *contentful.Resource, attrs map[string]interface{}) resource.TestCheckFunc { - return func(s *terraform.State) error { - - spaceIDCheck := attrs["space_id"].(string) - if upload.Sys.Space.Sys.ID != spaceIDCheck { - return fmt.Errorf("space id does not match: %s, %s", upload.Sys.Space.Sys.ID, spaceIDCheck) - } - - return nil - } -} - -func testAccContentfulUploadDestroy(s *terraform.State) error { - for _, rs := range s.RootModule().Resources { - if rs.Type != "contentful_entry" { - continue - } - - // get space id from resource data - spaceID := rs.Primary.Attributes["space_id"] - if spaceID == "" { - return fmt.Errorf("no space_id is set") - } - - // check webhook resource id - if rs.Primary.ID == "" { - return fmt.Errorf("no asset ID is set") - } - - // sdk client - client := testAccProvider.Meta().(*contentful.Client) - - asset, _ := client.Assets.Get(spaceID, rs.Primary.ID) - if asset == nil { - return nil - } - - return fmt.Errorf("asset still exists with id: %s", rs.Primary.ID) - } - - return nil -} - -var testAccContentfulUploadConfig = ` -resource "contentful_upload" "myupload" { - space_id = "` + spaceID + `" - file_path = "/home/kantoor/go/src/github.com/labd/terraform-contentful/local/upload_test.png" - asset_id = "upload_test" - locale = "en-US" - title = "This is an asset" - description = "Uploaded asset!" -} -` From 9aecdd95f2e0f86b520075218d1a83faf605c19a Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Fri, 3 Jul 2020 09:19:25 +0200 Subject: [PATCH 123/192] Uploads resource to different branch. --- contentful/contentful_go_.txt | 63 ++++++++ contentful/resource_contentful_upload.go | 148 ++++++++++++++++++ contentful/resource_contentful_upload_test.go | 110 +++++++++++++ 3 files changed, 321 insertions(+) create mode 100644 contentful/contentful_go_.txt create mode 100644 contentful/resource_contentful_upload.go create mode 100644 contentful/resource_contentful_upload_test.go diff --git a/contentful/contentful_go_.txt b/contentful/contentful_go_.txt new file mode 100644 index 0000000..5cd95f7 --- /dev/null +++ b/contentful/contentful_go_.txt @@ -0,0 +1,63 @@ +To make uploads resource work, the do function in the contentful go sdk +needs to be edited. This method will return an error containing the +response body. This is not included in the official repo, because this +is a temporary (and an ugly) fix. + +func (c *Client) do(req *http.Request, v interface{}) error { + if c.Debug == true { + command, _ := http2curl.GetCurlCommand(req) + fmt.Println(command) + } + + res, err := c.client.Do(req) + if err != nil { + return err + } + + if res.StatusCode >= 200 && res.StatusCode < 400 { + // Upload/Create Resource response cannot be decoded + if c.api == "URC" && req.Method == "POST" { + // Nulpointer workaround, set response as error and catch in service + buf := new(bytes.Buffer) + buf.ReadFrom(res.Body) + err = errors.New(buf.String()) + defer res.Body.Close() + return err + } else { + if v != nil { + defer res.Body.Close() + err = json.NewDecoder(res.Body).Decode(v) + if err != nil { + return err + } + } + } + + return nil + } + + // parse api response + apiError := c.handleError(req, res) + + // return apiError if it is not rate limit error + if _, ok := apiError.(RateLimitExceededError); !ok { + return apiError + } + + resetHeader := res.Header.Get("x-contentful-ratelimit-reset") + + // return apiError if Ratelimit-Reset header is not presented + if resetHeader == "" { + return apiError + } + + // wait X-Contentful-Ratelimit-Reset amount of seconds + waitSeconds, err := strconv.Atoi(resetHeader) + if err != nil { + return apiError + } + + time.Sleep(time.Second * time.Duration(waitSeconds)) + + return c.do(req, v) +} \ No newline at end of file diff --git a/contentful/resource_contentful_upload.go b/contentful/resource_contentful_upload.go new file mode 100644 index 0000000..fceb740 --- /dev/null +++ b/contentful/resource_contentful_upload.go @@ -0,0 +1,148 @@ +package contentful + +import ( + "encoding/json" + "fmt" + "github.com/hashicorp/terraform/helper/schema" + contentful "github.com/labd/contentful-go" +) + +func resourceContentfulUpload() *schema.Resource { + return &schema.Resource{ + Create: resourceCreateUpload, + Read: resourceReadUpload, + Update: nil, + Delete: resourceDeleteUpload, + + Schema: map[string]*schema.Schema{ + "space_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "file_path": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "asset_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "locale": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "title": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "description": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + }, + } +} + +func resourceCreateUpload(d *schema.ResourceData, m interface{}) (err error) { + uploadClient := contentful.NewResourceClient(CMAToken) + uploadClient.SetOrganization(orgID) + client := m.(*contentful.Client) + + upload := contentful.Resource{} + + fmt.Println(d.Get("space_id").(string)) + fmt.Println(d.Get("file_path").(string)) + + response := uploadClient.Resources.Create(d.Get("space_id").(string), d.Get("file_path").(string)) + err = json.Unmarshal([]byte(response.Error()), &upload) + + d.SetId(upload.Sys.ID) + + if err := setUploadProperties(d, &upload); err != nil { + return err + } + + asset := &contentful.Asset{ + Sys: &contentful.Sys{ + ID: d.Get("asset_id").(string), + Version: 0, + }, + Locale: d.Get("locale").(string), + Fields: &contentful.AssetFields{ + Title: map[string]string{ + d.Get("locale").(string): d.Get("title").(string), + }, + Description: map[string]string{ + d.Get("locale").(string): d.Get("description").(string), + }, + File: map[string]*contentful.File{ + d.Get("locale").(string): { + UploadFrom: &contentful.UploadFrom{ + Sys: &contentful.Sys{ + ID: "upload.Sys.ID", + LinkType: "Upload", + }, + }, + }, + }, + }, + } + + err = client.Assets.Upsert(d.Get("space_id").(string), asset) + if err != nil { + return err + } + + err = client.Assets.Process(d.Get("space_id").(string), asset) + if err != nil { + return err + } + + err = client.Assets.Publish(spaceID, asset) + if err != nil { + return err + } + + return err +} + +func resourceReadUpload(d *schema.ResourceData, m interface{}) (err error) { + client := m.(*contentful.Client) + spaceID := d.Get("space_id").(string) + uploadID := d.Id() + + upload, err := client.Resources.Get(spaceID, uploadID) + if _, ok := err.(contentful.NotFoundError); ok { + d.SetId("") + return err + } + + return setUploadProperties(d, upload) +} + +func resourceDeleteUpload(d *schema.ResourceData, m interface{}) (err error) { + client := m.(*contentful.Client) + spaceID := d.Get("space_id").(string) + uploadID := d.Id() + + _, err = client.Resources.Get(spaceID, uploadID) + if err != nil { + return err + } + + return client.Resources.Delete(spaceID, uploadID) +} + +func setUploadProperties(d *schema.ResourceData, resource *contentful.Resource) (err error) { + if err = d.Set("space_id", resource.Sys.Space.Sys.ID); err != nil { + return err + } + + return err +} diff --git a/contentful/resource_contentful_upload_test.go b/contentful/resource_contentful_upload_test.go new file mode 100644 index 0000000..047e71a --- /dev/null +++ b/contentful/resource_contentful_upload_test.go @@ -0,0 +1,110 @@ +package contentful + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + contentful "github.com/labd/contentful-go" +) + +func TestAccContentfulUpload_Basic(t *testing.T) { + var upload contentful.Resource + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccContentfulUploadDestroy, + Steps: []resource.TestStep{ + { + Config: testAccContentfulUploadConfig, + Check: resource.ComposeTestCheckFunc( + testAccCheckContentfulUploadExists("contentful_asset.myupload", &upload), + testAccCheckContentfulUploadAttributes(&upload, map[string]interface{}{ + "space_id": spaceID, + }), + ), + }, + }, + }) +} + +func testAccCheckContentfulUploadExists(n string, upload *contentful.Resource) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("not Found: %s", n) + } + + spaceID := rs.Primary.Attributes["space_id"] + if spaceID == "" { + return fmt.Errorf("no space_id is set") + } + + client := testAccProvider.Meta().(*contentful.Client) + + contentfulAsset, err := client.Resources.Get(spaceID, rs.Primary.ID) + if err != nil { + return err + } + + *upload = *contentfulAsset + + return nil + } +} + +func testAccCheckContentfulUploadAttributes(upload *contentful.Resource, attrs map[string]interface{}) resource.TestCheckFunc { + return func(s *terraform.State) error { + + spaceIDCheck := attrs["space_id"].(string) + if upload.Sys.Space.Sys.ID != spaceIDCheck { + return fmt.Errorf("space id does not match: %s, %s", upload.Sys.Space.Sys.ID, spaceIDCheck) + } + + return nil + } +} + +func testAccContentfulUploadDestroy(s *terraform.State) error { + for _, rs := range s.RootModule().Resources { + if rs.Type != "contentful_entry" { + continue + } + + // get space id from resource data + spaceID := rs.Primary.Attributes["space_id"] + if spaceID == "" { + return fmt.Errorf("no space_id is set") + } + + // check webhook resource id + if rs.Primary.ID == "" { + return fmt.Errorf("no asset ID is set") + } + + // sdk client + client := testAccProvider.Meta().(*contentful.Client) + + asset, _ := client.Assets.Get(spaceID, rs.Primary.ID) + if asset == nil { + return nil + } + + return fmt.Errorf("asset still exists with id: %s", rs.Primary.ID) + } + + return nil +} + +var testAccContentfulUploadConfig = ` +resource "contentful_upload" "myupload" { + space_id = "` + spaceID + `" + file_path = "/home/kantoor/go/src/github.com/labd/terraform-contentful/local/upload_test.png" + asset_id = "upload_test" + locale = "en-US" + title = "This is an asset" + description = "Uploaded asset!" +} +` From 0a8377b0d95a9db3a7a58256c2cd50840027c233 Mon Sep 17 00:00:00 2001 From: Tim Leguijt Date: Thu, 22 Oct 2020 11:21:53 +0200 Subject: [PATCH 124/192] Update README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a8b9bdf..5641631 100644 --- a/README.md +++ b/README.md @@ -150,7 +150,7 @@ Julien Fabre: [Writing a Terraform provider](http://blog.jfabre.net/2017/01/22/w ## Support -If you have a problem with this provider, please file an [issue](https://github.com/contentful-labs/terraform-contentful/issues/new) here on Github. +If you have a problem with this provider, please file an [issue](https://github.com/labd/terraform-provider-contentful/issues/new) here on Github. ## License From 8371bc7b7dfd2647ad750294ba1cd34fdac599fd Mon Sep 17 00:00:00 2001 From: Tim Leguijt Date: Thu, 22 Oct 2020 11:24:15 +0200 Subject: [PATCH 125/192] Change build make target --- Dockerfile-test | 11 ----------- Makefile | 4 ++-- install-dependencies.sh | 6 ------ 3 files changed, 2 insertions(+), 19 deletions(-) delete mode 100644 Dockerfile-test delete mode 100755 install-dependencies.sh diff --git a/Dockerfile-test b/Dockerfile-test deleted file mode 100644 index c03abc1..0000000 --- a/Dockerfile-test +++ /dev/null @@ -1,11 +0,0 @@ -FROM golang:1.14.2 - -WORKDIR /go/src/github.com/labd/terraform-contentful - -# http://stackoverflow.com/questions/39278756/cache-go-get-in-docker-build -COPY ./install-dependencies.sh /go/src/github.com/labd/terraform-contentful -RUN ./install-dependencies.sh - -COPY . /go/src/github.com/labd/terraform-contentful - -CMD go test -v \ No newline at end of file diff --git a/Makefile b/Makefile index 3b44a7a..ff80022 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ .PHONY: build build: - sudo -S docker build -t terraform-provider-contentful -f Dockerfile-test . + go build .PHONY: test-unit test-unit: build @@ -15,7 +15,7 @@ test-unit: build .PHONY: interactive interactive: sudo -S docker run -it \ - -v $(shell pwd):/go/src/github.com/labd/terraform-contentful \ + -v $(shell pwd):/go/src/github.com/labd/terraform-provider-contentful \ -e CONTENTFUL_MANAGEMENT_TOKEN=${CONTENTFUL_MANAGEMENT_TOKEN} \ -e CONTENTFUL_ORGANIZATION_ID=${CONTENTFUL_ORGANIZATION_ID} \ -e SPACE_ID=${SPACE_ID} \ diff --git a/install-dependencies.sh b/install-dependencies.sh deleted file mode 100755 index e2c4911..0000000 --- a/install-dependencies.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env bash - -go get github.com/hashicorp/terraform/terraform -go get github.com/hashicorp/terraform/helper/resource -go get github.com/hashicorp/terraform/helper/schema -go get github.com/labd/contentful-go From 3dc619355dababecbc44b2347b1298f6dd148f5a Mon Sep 17 00:00:00 2001 From: Tim Leguijt Date: Thu, 22 Oct 2020 11:24:48 +0200 Subject: [PATCH 126/192] Rename to terraform-provider-contentful --- README.md | 6 +- contentful/resource_contentful_upload_test.go | 2 +- go.mod | 4 +- go.sum | 439 ++++++++++++++++++ main.go | 2 +- 5 files changed, 446 insertions(+), 7 deletions(-) create mode 100644 go.sum diff --git a/README.md b/README.md index 5641631..cbeb1ed 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -![Go](https://github.com/labd/terraform-contentful/workflows/Go/badge.svg?branch=master) -[![codecov](https://codecov.io/gh/labd/terraform-contentful/branch/master/graph/badge.svg)](https://codecov.io/gh/labd/terraform-contentful) -[![license](https://img.shields.io/github/license/labd/terraform-contentful.svg)](https://github.com/labd/terraform-contentful/blob/master/LICENSE) +![Go](https://github.com/labd/terraform-provider-contentful/workflows/Go/badge.svg?branch=master) +[![codecov](https://codecov.io/gh/labd/terraform-provider-contentful/branch/master/graph/badge.svg)](https://codecov.io/gh/labd/terraform-provider-contentful) +[![license](https://img.shields.io/github/license/labd/terraform-provider-contentful.svg)](https://github.com/labd/terraform-provider-contentful/blob/master/LICENSE) Terraform Provider for [Contentful's](https://www.contentful.com) Content Management API diff --git a/contentful/resource_contentful_upload_test.go b/contentful/resource_contentful_upload_test.go index 047e71a..100feb4 100644 --- a/contentful/resource_contentful_upload_test.go +++ b/contentful/resource_contentful_upload_test.go @@ -101,7 +101,7 @@ func testAccContentfulUploadDestroy(s *terraform.State) error { var testAccContentfulUploadConfig = ` resource "contentful_upload" "myupload" { space_id = "` + spaceID + `" - file_path = "/home/kantoor/go/src/github.com/labd/terraform-contentful/local/upload_test.png" + file_path = "/home/kantoor/go/src/github.com/labd/terraform-provider-contentful/local/upload_test.png" asset_id = "upload_test" locale = "en-US" title = "This is an asset" diff --git a/go.mod b/go.mod index 0e73d39..5f5915c 100644 --- a/go.mod +++ b/go.mod @@ -1,8 +1,8 @@ -module github.com/labd/terraform-contentful +module github.com/labd/terraform-provider-contentful go 1.14 require ( github.com/hashicorp/terraform v0.12.24 - github.com/labd/contentful-go v0.4.1-0.20200508125900-edd2d77b81af + github.com/labd/contentful-go v0.4.1-0.20201022091751-47d2076a5ad8 ) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..e31fc30 --- /dev/null +++ b/go.sum @@ -0,0 +1,439 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +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/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/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/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc= +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/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/go.mod h1:MgwOyqaIuKdG4TL/2ywSsIWKAfJfgHDo8ObuUk3t5sA= +github.com/Azure/go-autorest/autorest/validation v0.2.0/go.mod h1:3EEqHnBxQGHXRYq3HT1WyXAvT7LLY3tl70hw6tQIbjI= +github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= +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/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU= +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/go.mod h1:nuWgzSkT5PnyOd+272uUmV0dnAnAn42Mk7PiQC5VzN4= +github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409/go.mod h1:1pk82RBxDY/JZnPQrtqHlUFfCctgdorsd9M06fMynOM= +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/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/go.mod h1:T9M45xf79ahXVelWoOBmH0y4aC1t5kXO5BxwyakgIGA= +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/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= +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/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= +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/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/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas= +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 h1:2bNwBOmhyFEFcoB3tGvTD5xanq+4kyOZlB8wFYbMjkk= +github.com/bmatcuk/doublestar v1.1.5/go.mod h1:wiQtGV+rzVYxB7WIlirSN++5HPtPlXEo9MEoZQC/PmE= +github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= +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/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/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/coreos/bbolt v1.3.0/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +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/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +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/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/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +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/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= +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/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/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +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/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +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/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +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= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +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/gophercloud/gophercloud v0.0.0-20190208042652-bc37892e1968/go.mod h1:3WdhXV3rUYy9p6AUW8d94kr+HS62Y4VL9mBnFxsD8q4= +github.com/gophercloud/utils v0.0.0-20190128072930-fbb6ab446f01/go.mod h1:wjDF8z83zTeg5eMLml5EBSlAhbF7G8DobyI1YsMuyzw= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +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/hashicorp/aws-sdk-go-base v0.4.0/go.mod h1:eRhlz3c4nhqxFZJAahJEFL7gh6Jyj5rQmQc7F9eHFyQ= +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/go.mod h1:YuAtHxm2v74s+IjQwUG88dHBJPd5jL+cXr5BGVzSKhE= +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= +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 h1:Yv9YzBlAETjy6AOX9eLBZ3nshNVRREgerT/3nvxlGho= +github.com/hashicorp/go-hclog v0.0.0-20181001195459-61d530d6c27f/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= +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 h1:hRho44SAoNu1CBtn5r8Q9J3rCs4ZverWZ4R+UeeNuWM= +github.com/hashicorp/go-plugin v1.0.1-0.20190610192547-a1bc61569a26/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/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/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/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= +github.com/hashicorp/go-version v1.2.0 h1:3vNe/fWF5CBgRIguda1meWhsZHy3m8gCJ5wx+dIzX/E= +github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/hcl v0.0.0-20170504190234-a4b07c25de5f h1:UdxlrJz4JOnY8W+DbLISwf2B8WXEolNRA8BGCwI9jws= +github.com/hashicorp/hcl v0.0.0-20170504190234-a4b07c25de5f/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w= +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/memberlist v0.1.0/go.mod h1:ncdBp14cuox2iFOq3kDiquKU6fqsTBc3W6JvZwjxxsE= +github.com/hashicorp/serf v0.0.0-20160124182025-e4ec8cc423bb/go.mod h1:h/Ru6tmZazX7WO/GDmwdpS975F019L4t5ng5IgwbNrE= +github.com/hashicorp/terraform v0.12.24 h1:lTTswsCcmTOhTwuUl2NdjtJBCNdGqZmRGQi0cjFHYOM= +github.com/hashicorp/terraform v0.12.24/go.mod h1:eJcloDEx5ywM4a1tetIuVrlqklM0bUVRYJBYAh4CYzA= +github.com/hashicorp/terraform-config-inspect v0.0.0-20191212124732-c6ae6269b9d7/go.mod h1:p+ivJws3dpqbp1iP84+npOyAmTTOLMgCzrXd3GSdn/A= +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 h1:b5rjCoWHc7eqmAS4/qyk21ZsHyb6Mxv/jykxvNTkU4M= +github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= +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/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/joyent/triton-go v0.0.0-20180313100802-d8f9c0314926/go.mod h1:U+RSyWxWd04xTqnuOQxnai7XGS2PrPY2cfGoDKtMHjA= +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/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +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/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/labd/contentful-go v0.4.1-0.20201022091751-47d2076a5ad8 h1:gtVR7knJ1J9OFoLH4wfzCr8cvn27b1V3JVrXgCwE59c= +github.com/labd/contentful-go v0.4.1-0.20201022091751-47d2076a5ad8/go.mod h1:nU9FmlPmgIOwTWg2czqlpRMhPQplTaPuPjuz0oIcftM= +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/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/lusis/go-artifactory v0.0.0-20160115162124-7e4ce345df82/go.mod h1:y54tfGmO3NKssKveTEFFzH8C/akrSOy/iW9qEAUDV84= +github.com/masterzen/simplexml v0.0.0-20160608183007-4572e39b1ab9/go.mod h1:kCEbxUJlNDEBNbdQMkPSp6yaKcRXVI6f4ddk8Riv4bc= +github.com/masterzen/winrm v0.0.0-20190223112901-5e5c9a7fe54b/go.mod h1:wr1VqkwW0AB5JS0QLy5GpVMS9E3VtRoSYXUYyVk46KY= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-shellwords v1.0.4/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= +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/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw= +github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ= +github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= +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/go.mod h1:OaY7UOoTkkrX3wRwjpYRKafIkkyeD0UtweSHAWWiqQM= +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= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +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/go.mod h1:pKvZHwWrZowLUzftuFq7coarnxbBXU4aQh3N0BJOeeA= +github.com/mitchellh/prefixedio v0.0.0-20190213213902-5733675afd51/go.mod h1:kB1naBgV9ORnkiTVeyJOI1DavaJkG4oNIq0Af6ZVKUo= +github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY= +github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +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/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/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/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/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_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/common v0.2.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/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +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/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +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/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/spf13/afero v1.2.1 h1:qgMbHoJbPbw579P+1zVY+6n4nIFuIchaIjzZ/I/Yq8M= +github.com/spf13/afero v1.2.1/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.1.4/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/svanharmelen/jsonapi v0.0.0-20180618144545-0c0828c3f16d/go.mod h1:BSTlc8jOjh0niykqEGVXOLXdi9o0r0kR8tCYiMvjFgw= +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/go.mod h1:wk2XFUg6egk4tSDNZtXeKfe2G6690UVyt163PuUxBZk= +github.com/terraform-providers/terraform-provider-openstack v1.15.0/go.mod h1:2aQ6n/BtChAl1y2S60vebhyJyZXBsuAI5G4+lHrT1Ew= +github.com/tmc/grpc-websocket-proxy v0.0.0-20171017195756-830351dc03c6/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/ugorji/go v0.0.0-20180813092308-00b869d2f4a5/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ= +github.com/ulikunitz/xz v0.5.5 h1:pFrO0lVpTBXLpYw+pnLj6TbvHuyjXMfjGeCwSqCVwok= +github.com/ulikunitz/xz v0.5.5/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8= +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/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= +github.com/xiang90/probing v0.0.0-20160813154853-07dd2e8dfe18/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xlab/treeprint v0.0.0-20161029104018-1d6e34225557/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/zclconf/go-cty v1.0.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s= +github.com/zclconf/go-cty v1.1.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s= +github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8= +github.com/zclconf/go-cty v1.2.1 h1:vGMsygfmeCl4Xb6OA5U5XVAaQZ69FvoG7X2jUtQujb8= +github.com/zclconf/go-cty v1.2.1/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8= +github.com/zclconf/go-cty-yaml v1.0.1 h1:up11wlgAaDvlAGENcFDnZgkn0qUJurso7k6EpURKNF8= +github.com/zclconf/go-cty-yaml v1.0.1/go.mod h1:IP3Ylp0wQpYm50IHK8OZWKMu6sPJIUgKa8XhiVHura0= +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/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/zap v1.9.1/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-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-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/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/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= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +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= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +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/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= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/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= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190804053845-51ab0e2deafa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +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/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200507205054-480da3ebd79c/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0 h1:jbyannxz0XFD3zdjgrSUsaJbgpH4eTrkdhRChkHPfO8= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1 h1:j6XxA85m/6txkUCHvzlV5f+HBNl/1r5cZ2A/3IEFOO8= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/cheggaaa/pb.v1 v1.0.27/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= +gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +moul.io/http2curl v1.0.1-0.20190925090545-5cd742060b0e h1:C7q+e9M5nggAvWfVg9Nl66kebKeuJlP3FD58V4RR5wo= +moul.io/http2curl v1.0.1-0.20190925090545-5cd742060b0e/go.mod h1:nejbQVfXh96n9dSF6cH3Jsk/QI1Z2oEL7sSI2ifXFNA= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/main.go b/main.go index ff4faff..a2e9b51 100644 --- a/main.go +++ b/main.go @@ -3,7 +3,7 @@ package main import ( "github.com/hashicorp/terraform/plugin" "github.com/hashicorp/terraform/terraform" - "github.com/labd/terraform-contentful/contentful" + "github.com/labd/terraform-provider-contentful/contentful" ) func main() { From 6418d3d59bb03885abc0919de61949b52bd30cc7 Mon Sep 17 00:00:00 2001 From: Tim Leguijt Date: Thu, 22 Oct 2020 22:53:55 +0200 Subject: [PATCH 127/192] Set contentful-go to v0.5.0 --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 5f5915c..13c4914 100644 --- a/go.mod +++ b/go.mod @@ -4,5 +4,5 @@ go 1.14 require ( github.com/hashicorp/terraform v0.12.24 - github.com/labd/contentful-go v0.4.1-0.20201022091751-47d2076a5ad8 + github.com/labd/contentful-go v0.5.0 ) diff --git a/go.sum b/go.sum index e31fc30..1c9388f 100644 --- a/go.sum +++ b/go.sum @@ -201,6 +201,8 @@ github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LE github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/labd/contentful-go v0.4.1-0.20201022091751-47d2076a5ad8 h1:gtVR7knJ1J9OFoLH4wfzCr8cvn27b1V3JVrXgCwE59c= github.com/labd/contentful-go v0.4.1-0.20201022091751-47d2076a5ad8/go.mod h1:nU9FmlPmgIOwTWg2czqlpRMhPQplTaPuPjuz0oIcftM= +github.com/labd/contentful-go v0.5.0 h1:nm7dHLDkNPZ6ZkxCoIy4Xo7/UcYsmJdOxS+SK8RIXhw= +github.com/labd/contentful-go v0.5.0/go.mod h1:nU9FmlPmgIOwTWg2czqlpRMhPQplTaPuPjuz0oIcftM= 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= From b8fa4e2adcf84a06b5b8c6c93187bb7193c09161 Mon Sep 17 00:00:00 2001 From: Tim Leguijt Date: Thu, 22 Oct 2020 22:54:05 +0200 Subject: [PATCH 128/192] Add release action --- .github/workflows/release.yml | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..3b65d7c --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,31 @@ +name: release +on: + push: + tags: + - 'v*' +jobs: + goreleaser: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Unshallow + run: git fetch --prune --unshallow + - name: Set up Go + uses: actions/setup-go@v2 + with: + go-version: 1.14 + - name: Import GPG key + id: import_gpg + uses: paultyng/ghaction-import-gpg@v2.1.0 + env: + GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} + PASSPHRASE: ${{ secrets.PASSPHRASE }} + - name: Run GoReleaser + uses: goreleaser/goreleaser-action@v2 + with: + version: latest + args: release --rm-dist + env: + GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From c45419aeaffa40b0acecf72ea45648653f68215d Mon Sep 17 00:00:00 2001 From: Tim Leguijt Date: Thu, 22 Oct 2020 22:55:53 +0200 Subject: [PATCH 129/192] Prepare changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..5416738 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,3 @@ +0.1.0 (unreleased) +================== +Initial release \ No newline at end of file From d66f90aac7813bfac4afe123442a3aae55c2cbef Mon Sep 17 00:00:00 2001 From: Tim Leguijt Date: Mon, 26 Oct 2020 09:47:55 +0100 Subject: [PATCH 130/192] Removed unfinished 'upload' resources Were placed in seperate branch --- contentful/resource_contentful_upload.go | 148 ------------------ contentful/resource_contentful_upload_test.go | 110 ------------- 2 files changed, 258 deletions(-) delete mode 100644 contentful/resource_contentful_upload.go delete mode 100644 contentful/resource_contentful_upload_test.go diff --git a/contentful/resource_contentful_upload.go b/contentful/resource_contentful_upload.go deleted file mode 100644 index fceb740..0000000 --- a/contentful/resource_contentful_upload.go +++ /dev/null @@ -1,148 +0,0 @@ -package contentful - -import ( - "encoding/json" - "fmt" - "github.com/hashicorp/terraform/helper/schema" - contentful "github.com/labd/contentful-go" -) - -func resourceContentfulUpload() *schema.Resource { - return &schema.Resource{ - Create: resourceCreateUpload, - Read: resourceReadUpload, - Update: nil, - Delete: resourceDeleteUpload, - - Schema: map[string]*schema.Schema{ - "space_id": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - }, - "file_path": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - }, - "asset_id": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - }, - "locale": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - }, - "title": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - }, - "description": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - }, - }, - } -} - -func resourceCreateUpload(d *schema.ResourceData, m interface{}) (err error) { - uploadClient := contentful.NewResourceClient(CMAToken) - uploadClient.SetOrganization(orgID) - client := m.(*contentful.Client) - - upload := contentful.Resource{} - - fmt.Println(d.Get("space_id").(string)) - fmt.Println(d.Get("file_path").(string)) - - response := uploadClient.Resources.Create(d.Get("space_id").(string), d.Get("file_path").(string)) - err = json.Unmarshal([]byte(response.Error()), &upload) - - d.SetId(upload.Sys.ID) - - if err := setUploadProperties(d, &upload); err != nil { - return err - } - - asset := &contentful.Asset{ - Sys: &contentful.Sys{ - ID: d.Get("asset_id").(string), - Version: 0, - }, - Locale: d.Get("locale").(string), - Fields: &contentful.AssetFields{ - Title: map[string]string{ - d.Get("locale").(string): d.Get("title").(string), - }, - Description: map[string]string{ - d.Get("locale").(string): d.Get("description").(string), - }, - File: map[string]*contentful.File{ - d.Get("locale").(string): { - UploadFrom: &contentful.UploadFrom{ - Sys: &contentful.Sys{ - ID: "upload.Sys.ID", - LinkType: "Upload", - }, - }, - }, - }, - }, - } - - err = client.Assets.Upsert(d.Get("space_id").(string), asset) - if err != nil { - return err - } - - err = client.Assets.Process(d.Get("space_id").(string), asset) - if err != nil { - return err - } - - err = client.Assets.Publish(spaceID, asset) - if err != nil { - return err - } - - return err -} - -func resourceReadUpload(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Client) - spaceID := d.Get("space_id").(string) - uploadID := d.Id() - - upload, err := client.Resources.Get(spaceID, uploadID) - if _, ok := err.(contentful.NotFoundError); ok { - d.SetId("") - return err - } - - return setUploadProperties(d, upload) -} - -func resourceDeleteUpload(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Client) - spaceID := d.Get("space_id").(string) - uploadID := d.Id() - - _, err = client.Resources.Get(spaceID, uploadID) - if err != nil { - return err - } - - return client.Resources.Delete(spaceID, uploadID) -} - -func setUploadProperties(d *schema.ResourceData, resource *contentful.Resource) (err error) { - if err = d.Set("space_id", resource.Sys.Space.Sys.ID); err != nil { - return err - } - - return err -} diff --git a/contentful/resource_contentful_upload_test.go b/contentful/resource_contentful_upload_test.go deleted file mode 100644 index 100feb4..0000000 --- a/contentful/resource_contentful_upload_test.go +++ /dev/null @@ -1,110 +0,0 @@ -package contentful - -import ( - "fmt" - "testing" - - "github.com/hashicorp/terraform/helper/resource" - "github.com/hashicorp/terraform/terraform" - contentful "github.com/labd/contentful-go" -) - -func TestAccContentfulUpload_Basic(t *testing.T) { - var upload contentful.Resource - - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccContentfulUploadDestroy, - Steps: []resource.TestStep{ - { - Config: testAccContentfulUploadConfig, - Check: resource.ComposeTestCheckFunc( - testAccCheckContentfulUploadExists("contentful_asset.myupload", &upload), - testAccCheckContentfulUploadAttributes(&upload, map[string]interface{}{ - "space_id": spaceID, - }), - ), - }, - }, - }) -} - -func testAccCheckContentfulUploadExists(n string, upload *contentful.Resource) resource.TestCheckFunc { - return func(s *terraform.State) error { - rs, ok := s.RootModule().Resources[n] - if !ok { - return fmt.Errorf("not Found: %s", n) - } - - spaceID := rs.Primary.Attributes["space_id"] - if spaceID == "" { - return fmt.Errorf("no space_id is set") - } - - client := testAccProvider.Meta().(*contentful.Client) - - contentfulAsset, err := client.Resources.Get(spaceID, rs.Primary.ID) - if err != nil { - return err - } - - *upload = *contentfulAsset - - return nil - } -} - -func testAccCheckContentfulUploadAttributes(upload *contentful.Resource, attrs map[string]interface{}) resource.TestCheckFunc { - return func(s *terraform.State) error { - - spaceIDCheck := attrs["space_id"].(string) - if upload.Sys.Space.Sys.ID != spaceIDCheck { - return fmt.Errorf("space id does not match: %s, %s", upload.Sys.Space.Sys.ID, spaceIDCheck) - } - - return nil - } -} - -func testAccContentfulUploadDestroy(s *terraform.State) error { - for _, rs := range s.RootModule().Resources { - if rs.Type != "contentful_entry" { - continue - } - - // get space id from resource data - spaceID := rs.Primary.Attributes["space_id"] - if spaceID == "" { - return fmt.Errorf("no space_id is set") - } - - // check webhook resource id - if rs.Primary.ID == "" { - return fmt.Errorf("no asset ID is set") - } - - // sdk client - client := testAccProvider.Meta().(*contentful.Client) - - asset, _ := client.Assets.Get(spaceID, rs.Primary.ID) - if asset == nil { - return nil - } - - return fmt.Errorf("asset still exists with id: %s", rs.Primary.ID) - } - - return nil -} - -var testAccContentfulUploadConfig = ` -resource "contentful_upload" "myupload" { - space_id = "` + spaceID + `" - file_path = "/home/kantoor/go/src/github.com/labd/terraform-provider-contentful/local/upload_test.png" - asset_id = "upload_test" - locale = "en-US" - title = "This is an asset" - description = "Uploaded asset!" -} -` From b68e1086868b41b1d17f896779ba1067940534d8 Mon Sep 17 00:00:00 2001 From: Tim Leguijt Date: Mon, 26 Oct 2020 09:51:06 +0100 Subject: [PATCH 131/192] v0.1.0 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5416738..d2ca120 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,3 @@ -0.1.0 (unreleased) +0.1.0 (2020-10-26) ================== Initial release \ No newline at end of file From aee5e2db5e5e24d83ac851b769bf208543ba4f38 Mon Sep 17 00:00:00 2001 From: Tim Leguijt Date: Mon, 26 Oct 2020 10:40:53 +0100 Subject: [PATCH 132/192] Add goreleaser --- .goreleaser.yml | 55 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 .goreleaser.yml diff --git a/.goreleaser.yml b/.goreleaser.yml new file mode 100644 index 0000000..3166e83 --- /dev/null +++ b/.goreleaser.yml @@ -0,0 +1,55 @@ +project_name: terraform-provider-contenful + +builds: +- env: + # goreleaser does not work with CGO, it could also complicate + # usage by users in CI/CD systems like Terraform Cloud where + # they are unable to install libraries. + - CGO_ENABLED=0 + mod_timestamp: '{{ .CommitTimestamp }}' + flags: + - -trimpath + ldflags: + - '-s -w -X main.version={{.Version}} -X main.commit={{.Commit}}' + goos: + - freebsd + - windows + - linux + - darwin + goarch: + - amd64 + - '386' + - arm + - arm64 + ignore: + - goos: darwin + goarch: '386' + binary: '{{ .ProjectName }}_v{{ .Version }}' + +archives: +- format: zip + name_template: '{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}' + +checksum: + name_template: '{{ .ProjectName }}_{{ .Version }}_SHA256SUMS' + algorithm: sha256 + +changelog: + sort: asc + filters: + exclude: + - "^docs:" + - "^test:" + +signs: + - artifacts: checksum + args: + # if you are using this is a GitHub action or some other automated pipeline, you + # need to pass the batch flag to indicate its not interactive. + - "--batch" + - "--local-user" + - "{{ .Env.GPG_FINGERPRINT }}" # set this environment variable for your signing key + - "--output" + - "${signature}" + - "--detach-sign" + - "${artifact}" From 617cc49da118da27897f88fbfa332f1c39b2638d Mon Sep 17 00:00:00 2001 From: Tim Leguijt Date: Mon, 26 Oct 2020 11:05:05 +0100 Subject: [PATCH 133/192] Fixed typo --- .goreleaser.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.goreleaser.yml b/.goreleaser.yml index 3166e83..fb1141f 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -1,4 +1,4 @@ -project_name: terraform-provider-contenful +project_name: terraform-provider-contentful builds: - env: From d7e829fa2b89afa5d5e962477d484579a6443ca5 Mon Sep 17 00:00:00 2001 From: Tim Leguijt Date: Mon, 26 Oct 2020 12:21:13 +0100 Subject: [PATCH 134/192] try GPG_PASSPHRASE --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3b65d7c..e97c501 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -20,7 +20,7 @@ jobs: uses: paultyng/ghaction-import-gpg@v2.1.0 env: GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} - PASSPHRASE: ${{ secrets.PASSPHRASE }} + PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} - name: Run GoReleaser uses: goreleaser/goreleaser-action@v2 with: From 6ebcd3687b83a2ffa6e5f0b369ab0ed6263df95c Mon Sep 17 00:00:00 2001 From: Querijn de Graaf Date: Thu, 29 Apr 2021 22:17:23 +0200 Subject: [PATCH 135/192] Add `testacc` option to makefile to run without docker, update changelog --- CHANGELOG.md | 15 +++++++++++++++ Makefile | 8 +++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d2ca120..21e6f99 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,18 @@ +0.3.0 (2021-04-29) +================== +Re-release of 0.1.0 to fix registry. +# Features + +Create, update and delete Contentful resources: +- [x] Spaces +- [x] Content Types +- [x] API Keys +- [x] Webhooks +- [x] Locales +- [x] Environments +- [x] Entries +- [x] Assets + 0.1.0 (2020-10-26) ================== Initial release \ No newline at end of file diff --git a/Makefile b/Makefile index ff80022..46a67b4 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,8 @@ -.PHONY: build +.PHONY: build, test-unit, interactive, testacc + build: go build -.PHONY: test-unit test-unit: build sudo docker run \ -e CONTENTFUL_MANAGEMENT_TOKEN=${CONTENTFUL_MANAGEMENT_TOKEN} \ @@ -12,7 +12,6 @@ test-unit: build terraform-provider-contentful \ go test ./... -v -.PHONY: interactive interactive: sudo -S docker run -it \ -v $(shell pwd):/go/src/github.com/labd/terraform-provider-contentful \ @@ -21,3 +20,6 @@ interactive: -e SPACE_ID=${SPACE_ID} \ terraform-provider-contentful \ bash + +testacc: + TF_ACC=1 go test -v ./... From e49c1d42203fc9cae84b92b9d52da7b3e3bbce90 Mon Sep 17 00:00:00 2001 From: Ard-Jan Aalberts Date: Fri, 30 Apr 2021 15:31:03 +0200 Subject: [PATCH 136/192] Fix validations issue (#8) * fix: validations bug fix Validations were not saved to the content models. I reverted the validations into the original schema, which makes the validations work for now. Keep in mind: this should be fixed in the future! --- contentful/resource_contentful_contenttype.go | 401 +----------------- .../resource_contentful_contenttype_test.go | 13 +- 2 files changed, 11 insertions(+), 403 deletions(-) diff --git a/contentful/resource_contentful_contenttype.go b/contentful/resource_contentful_contenttype.go index 59ebf4b..e160dcb 100644 --- a/contentful/resource_contentful_contenttype.go +++ b/contentful/resource_contentful_contenttype.go @@ -3,7 +3,6 @@ package contentful import ( "github.com/hashicorp/terraform/helper/schema" contentful "github.com/labd/contentful-go" - "time" ) func resourceContentfulContentType() *schema.Resource { @@ -70,10 +69,10 @@ func resourceContentfulContentType() *schema.Resource { Type: schema.TypeString, Required: true, }, - "validation": { + "validations": { Type: schema.TypeList, Optional: true, - Elem: generateValidationSchema(), + Elem: &schema.Schema{Type: schema.TypeString}, }, }, }, @@ -98,10 +97,10 @@ func resourceContentfulContentType() *schema.Resource { Optional: true, Default: false, }, - "validation": { + "validations": { Type: schema.TypeList, Optional: true, - Elem: generateValidationSchema(), + Elem: &schema.Schema{Type: schema.TypeString}, }, }, }, @@ -356,395 +355,3 @@ func processItems(fieldItems []interface{}) *contentful.FieldTypeArrayItem { } return items } - -// Expanders -// noinspection GoUnusedFunction -func expandContentTypeField(in interface{}) *contentful.Field { - field := &contentful.Field{} - m := in.(map[string]interface{}) - if v, ok := m["id"].(string); ok { - field.ID = v - } - if v, ok := m["name"].(string); ok { - field.Name = v - } - if v, ok := m["type"].(string); ok { - field.Type = v - } - if v, ok := m["link_type"].(string); ok { - field.LinkType = v - } - if v, ok := m["required"].(bool); ok { - field.Required = v - } - if v, ok := m["localized"].(bool); ok { - field.Localized = v - } - if v, ok := m["disabled"].(bool); ok { - field.Disabled = v - } - if v, ok := m["omitted"].(bool); ok { - field.Omitted = v - } - if v, ok := m["validation"].([]interface{}); ok && len(v) > 0 { - validations := make([]contentful.FieldValidation, len(v)) - for i, val := range v { - validations[i] = expandContentTypeFieldValidation(val) - } - field.Validations = validations - } - return field -} - -func expandContentTypeFieldValidation(in interface{}) contentful.FieldValidation { - m := in.(map[string]interface{}) - if v, ok := m["link"].([]string); ok { - return contentful.FieldValidationLink{ - LinkContentType: v, - } - } - if v, ok := m["mime_type"].([]string); ok { - return contentful.FieldValidationMimeType{ - MimeTypes: v, - } - } - if v, ok := m["dimension"].([]interface{}); ok { - return expandContentTypeFieldValidationDimension(v) - } - if v, ok := m["size"].([]interface{}); ok { - return expandContentTypeFieldValidationSize(v) - } - if v, ok := m["file_size"].([]interface{}); ok { - return expandContentTypeFieldValidationFileSize(v) - } - if v, ok := m["unique"].(bool); ok { - return contentful.FieldValidationUnique{ - Unique: v, - } - } - if v, ok := m["range"].([]interface{}); ok { - return expandContentTypeFieldValidationRange(v) - } - if v, ok := m["date"].([]interface{}); ok { - return expandContentTypeFieldValidationDate(v) - } - return nil -} - -func expandContentTypeFieldValidationDimension(in []interface{}) contentful.FieldValidation { - if len(in) == 0 || in[0] == nil { - return contentful.FieldValidationDimension{} - } - - validation := contentful.FieldValidationDimension{} - m := in[0].(map[string]interface{}) - if v, ok := m["min_width"].(float64); ok { - if validation.Width == nil { - validation.Width = &contentful.MinMax{} - } - validation.Width.Min = v - } - if v, ok := m["max_width"].(float64); ok { - if validation.Width == nil { - validation.Width = &contentful.MinMax{} - } - validation.Width.Max = v - } - if v, ok := m["min_height"].(float64); ok { - if validation.Height == nil { - validation.Width = &contentful.MinMax{} - } - validation.Height.Min = v - } - if v, ok := m["max_height"].(float64); ok { - if validation.Height == nil { - validation.Width = &contentful.MinMax{} - } - validation.Height.Max = v - } - if v, ok := m["err_message"].(string); ok { - validation.ErrorMessage = v - } - return validation -} - -func expandContentTypeFieldValidationSize(in []interface{}) contentful.FieldValidation { - if len(in) == 0 || in[0] == nil { - return contentful.FieldValidationSize{} - } - - validation := contentful.FieldValidationSize{} - m := in[0].(map[string]interface{}) - if v, ok := m["min"].(float64); ok { - if validation.Size == nil { - validation.Size = &contentful.MinMax{} - } - validation.Size.Min = v - } - if v, ok := m["max"].(float64); ok { - if validation.Size == nil { - validation.Size = &contentful.MinMax{} - } - validation.Size.Max = v - } - if v, ok := m["err_message"].(string); ok { - validation.ErrorMessage = v - } - return validation -} - -func expandContentTypeFieldValidationFileSize(in []interface{}) contentful.FieldValidation { - if len(in) == 0 || in[0] == nil { - return contentful.FieldValidationFileSize{} - } - - validation := contentful.FieldValidationFileSize{} - m := in[0].(map[string]interface{}) - if v, ok := m["min"].(float64); ok { - if validation.Size == nil { - validation.Size = &contentful.MinMax{} - } - validation.Size.Min = v - } - if v, ok := m["max"].(float64); ok { - if validation.Size == nil { - validation.Size = &contentful.MinMax{} - } - validation.Size.Max = v - } - if v, ok := m["err_message"].(string); ok { - validation.ErrorMessage = v - } - return validation -} - -func expandContentTypeFieldValidationRange(in []interface{}) contentful.FieldValidation { - if len(in) == 0 || in[0] == nil { - return contentful.FieldValidationRange{} - } - - validation := contentful.FieldValidationRange{} - m := in[0].(map[string]interface{}) - if v, ok := m["min"].(float64); ok { - if validation.Range == nil { - validation.Range = &contentful.MinMax{} - } - validation.Range.Min = v - } - if v, ok := m["max"].(float64); ok { - if validation.Range == nil { - validation.Range = &contentful.MinMax{} - } - validation.Range.Max = v - } - if v, ok := m["err_message"].(string); ok { - validation.ErrorMessage = v - } - return validation -} - -func expandContentTypeFieldValidationDate(in []interface{}) contentful.FieldValidation { - if len(in) == 0 || in[0] == nil { - return contentful.FieldValidationDate{} - } - - validation := contentful.FieldValidationDate{} - m := in[0].(map[string]interface{}) - if v, ok := m["min"].(time.Time); ok { - if validation.Range == nil { - validation.Range = &contentful.DateMinMax{} - } - validation.Range.Min = v - } - if v, ok := m["max"].(time.Time); ok { - if validation.Range == nil { - validation.Range = &contentful.DateMinMax{} - } - validation.Range.Max = v - } - if v, ok := m["err_message"].(string); ok { - validation.ErrorMessage = v - } - return validation -} - -// noinspection GoUnusedFunction -func expandContentTypeFieldValidationRegex(in []interface{}) contentful.FieldValidation { - if len(in) == 0 || in[0] == nil { - return contentful.FieldValidationRegex{} - } - - validation := contentful.FieldValidationRegex{} - m := in[0].(map[string]interface{}) - if v, ok := m["pattern"].(string); ok { - if validation.Regex == nil { - validation.Regex = &contentful.Regex{} - } - validation.Regex.Pattern = v - } - if v, ok := m["flags"].(string); ok { - if validation.Regex == nil { - validation.Regex = &contentful.Regex{} - } - validation.Regex.Flags = v - } - if v, ok := m["err_message"].(string); ok { - validation.ErrorMessage = v - } - return validation -} - -func generateValidationSchema() *schema.Resource { - return &schema.Resource{ - Schema: map[string]*schema.Schema{ - "link": { - Type: schema.TypeSet, - Optional: true, - Elem: &schema.Schema{Type: schema.TypeString}, - }, - "mime_type": { - Type: schema.TypeSet, - Optional: true, - Elem: &schema.Schema{Type: schema.TypeString}, - }, - "dimension": { - Type: schema.TypeList, - Optional: true, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "min_width": { - Type: schema.TypeFloat, - Required: true, - }, - "max_width": { - Type: schema.TypeFloat, - Required: true, - }, - "min_height": { - Type: schema.TypeFloat, - Required: true, - }, - "max_height": { - Type: schema.TypeFloat, - Required: true, - }, - "err_message": { - Type: schema.TypeString, - Required: true, - }, - }, - }, - }, - "size": { - Type: schema.TypeList, - Optional: true, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "min": { - Type: schema.TypeFloat, - Optional: true, - }, - "max": { - Type: schema.TypeFloat, - Optional: true, - }, - "err_message": { - Type: schema.TypeString, - Optional: true, - }, - }, - }, - }, - "file_size": { - Type: schema.TypeList, - Optional: true, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "min": { - Type: schema.TypeFloat, - Optional: true, - }, - "max": { - Type: schema.TypeFloat, - Optional: true, - }, - "err_message": { - Type: schema.TypeString, - Optional: true, - }, - }, - }, - }, - "unique": { - Type: schema.TypeBool, - Optional: true, - }, - "range": { - Type: schema.TypeList, - Optional: true, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "min": { - Type: schema.TypeFloat, - Optional: true, - }, - "max": { - Type: schema.TypeFloat, - Optional: true, - }, - "err_message": { - Type: schema.TypeString, - Optional: true, - }, - }, - }, - }, - "date": { - Type: schema.TypeList, - Optional: true, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "min": { - Type: schema.TypeString, - Optional: true, - }, - "max": { - Type: schema.TypeString, - Optional: true, - }, - "err_message": { - Type: schema.TypeString, - Optional: true, - }, - }, - }, - }, - "regex": { - Type: schema.TypeList, - Optional: true, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "pattern": { - Type: schema.TypeString, - Optional: true, - }, - "flags": { - Type: schema.TypeString, - Optional: true, - }, - "err_message": { - Type: schema.TypeString, - Optional: true, - }, - }, - }, - }, - }, - } -} diff --git a/contentful/resource_contentful_contenttype_test.go b/contentful/resource_contentful_contenttype_test.go index 68d30cc..3cb80f7 100644 --- a/contentful/resource_contentful_contenttype_test.go +++ b/contentful/resource_contentful_contenttype_test.go @@ -188,12 +188,13 @@ resource "contentful_contenttype" "mylinked_contenttype" { name = "Entry Link Field" type = "Link" link_type = "Entry" - dynamic "validation" { - for_each = ["{\"linkContentType\": [\"${contentful_contenttype.mycontenttype.id}\"]}"] - content { - link = lookup(contentful_contenttype.mycontenttype, "link", null) - } - } + validations = [ + jsonencode({ + linkContentType = [ + contentful_contenttype.mycontenttype.id + ] + }) + ] required = false } } From c719cf1e3a7601c24712e4b29baa588e2af14d67 Mon Sep 17 00:00:00 2001 From: Querijn de Graaf Date: Fri, 30 Apr 2021 15:38:23 +0200 Subject: [PATCH 137/192] Update Changelog --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 21e6f99..a19058c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +0.3.1 (2021-04-30) +================== +# Fixes + +* Fixed a bug causing validations in fields to not be saved properly to the models + 0.3.0 (2021-04-29) ================== Re-release of 0.1.0 to fix registry. From e5d94ba95519e953a09ed63406bf733ca68a0eb1 Mon Sep 17 00:00:00 2001 From: Querijn de Graaf Date: Thu, 3 Jun 2021 15:06:12 +0200 Subject: [PATCH 138/192] Add tfplugindocs generated docs with examples, update gitignore --- .gitignore | 1 - docs/index.md | 21 ++++ docs/resources/apikey.md | 42 ++++++++ docs/resources/asset.md | 87 ++++++++++++++++ docs/resources/contenttype.md | 98 +++++++++++++++++++ docs/resources/entry.md | 67 +++++++++++++ docs/resources/environment.md | 38 +++++++ docs/resources/locale.md | 49 ++++++++++ docs/resources/space.md | 37 +++++++ docs/resources/webhook.md | 55 +++++++++++ .../resources/contentful_apikey/resource.tf | 6 ++ .../resources/contentful_asset/resource.tf | 23 +++++ .../contentful_contenttype/resource.tf | 30 ++++++ .../resources/contentful_entry/resource.tf | 19 ++++ .../contentful_environment/resource.tf | 4 + .../resources/contentful_locale/resource.tf | 10 ++ .../resources/contentful_space/resource.tf | 3 + .../resources/contentful_webhook/resource.tf | 16 +++ 18 files changed, 605 insertions(+), 1 deletion(-) create mode 100644 docs/index.md create mode 100644 docs/resources/apikey.md create mode 100644 docs/resources/asset.md create mode 100644 docs/resources/contenttype.md create mode 100644 docs/resources/entry.md create mode 100644 docs/resources/environment.md create mode 100644 docs/resources/locale.md create mode 100644 docs/resources/space.md create mode 100644 docs/resources/webhook.md create mode 100644 examples/resources/contentful_apikey/resource.tf create mode 100644 examples/resources/contentful_asset/resource.tf create mode 100644 examples/resources/contentful_contenttype/resource.tf create mode 100644 examples/resources/contentful_entry/resource.tf create mode 100644 examples/resources/contentful_environment/resource.tf create mode 100644 examples/resources/contentful_locale/resource.tf create mode 100644 examples/resources/contentful_space/resource.tf create mode 100644 examples/resources/contentful_webhook/resource.tf diff --git a/.gitignore b/.gitignore index 15dc197..42d73fc 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,6 @@ terraform-provider-contentful /dist/* coverage.txt -*.tf .terraform/ terraform.* crash.log diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..bdabb85 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,21 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "contentful Provider" +subcategory: "" +description: |- + +--- + +# contentful Provider + + + + + + +## Schema + +### Required + +- **cma_token** (String) The Contentful Management API token +- **organization_id** (String) The organization ID diff --git a/docs/resources/apikey.md b/docs/resources/apikey.md new file mode 100644 index 0000000..a28ec1b --- /dev/null +++ b/docs/resources/apikey.md @@ -0,0 +1,42 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "contentful_apikey Resource - terraform-provider-contentful" +subcategory: "" +description: |- + +--- + +# contentful_apikey (Resource) + + + +## Example Usage + +```terraform +resource "contentful_apikey" "myapikey" { + space_id = "space-id" + + name = "api-key-name" + description = "a-great-key" +} +``` + + +## Schema + +### Required + +- **name** (String) +- **space_id** (String) + +### Optional + +- **description** (String) +- **id** (String) The ID of this resource. + +### Read-Only + +- **access_token** (String) +- **version** (Number) + + diff --git a/docs/resources/asset.md b/docs/resources/asset.md new file mode 100644 index 0000000..602b68a --- /dev/null +++ b/docs/resources/asset.md @@ -0,0 +1,87 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "contentful_asset Resource - terraform-provider-contentful" +subcategory: "" +description: |- + +--- + +# contentful_asset (Resource) + + + +## Example Usage + +```terraform +resource "contentful_asset" "example_asset" { + asset_id = "test_asset" + locale = "en-US" + space_id = "space-id" + + fields { + title { + locale = "en-US" + content = "asset title" + } + description { + locale = "en-US" + content = "asset description" + } + file = { + upload = "https://images.ctfassets.net/fo9twyrwpveg/2VQx7vz73aMEYi20MMgCk0/66e502115b1f1f973a944b4bd2cc536f/IC-1H_Modern_Stack_Website.svg" + fileName = "example.jpeg" + contentType = "image/jpeg" + } + } + published = false + archived = false +} +``` + + +## Schema + +### Required + +- **archived** (Boolean) +- **asset_id** (String) +- **fields** (Block List, Min: 1) (see [below for nested schema](#nestedblock--fields)) +- **locale** (String) +- **published** (Boolean) +- **space_id** (String) + +### Optional + +- **id** (String) The ID of this resource. + +### Read-Only + +- **version** (Number) + + +### Nested Schema for `fields` + +Required: + +- **description** (Block List, Min: 1) (see [below for nested schema](#nestedblock--fields--description)) +- **file** (Map of String) +- **title** (Block List, Min: 1) (see [below for nested schema](#nestedblock--fields--title)) + + +### Nested Schema for `fields.description` + +Required: + +- **content** (String) +- **locale** (String) + + + +### Nested Schema for `fields.title` + +Required: + +- **content** (String) +- **locale** (String) + + diff --git a/docs/resources/contenttype.md b/docs/resources/contenttype.md new file mode 100644 index 0000000..67ef6d8 --- /dev/null +++ b/docs/resources/contenttype.md @@ -0,0 +1,98 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "contentful_contenttype Resource - terraform-provider-contentful" +subcategory: "" +description: |- + +--- + +# contentful_contenttype (Resource) + + + +## Example Usage + +```terraform +resource "contentful_contenttype" "example_contenttype" { + space_id = "space-id" + name = "tf_linked" + description = "content type description" + display_field = "asset_field" + field { + id = "asset_field" + name = "Asset Field" + type = "Array" + items { + type = "Link" + link_type = "Asset" + } + required = true + } + field { + id = "entry_link_field" + name = "Entry Link Field" + type = "Link" + link_type = "Entry" + validations = [ + jsonencode({ + linkContentType = [ + contentful_contenttype.some_other_content_type.id + ] + }) + ] + required = false + } +} +``` + + +## Schema + +### Required + +- **display_field** (String) +- **field** (Block List, Min: 1) (see [below for nested schema](#nestedblock--field)) +- **name** (String) +- **space_id** (String) + +### Optional + +- **description** (String) +- **id** (String) The ID of this resource. + +### Read-Only + +- **version** (Number) + + +### Nested Schema for `field` + +Required: + +- **id** (String) The ID of this resource. +- **name** (String) +- **type** (String) + +Optional: + +- **disabled** (Boolean) +- **items** (Block List, Max: 1) (see [below for nested schema](#nestedblock--field--items)) +- **link_type** (String) +- **localized** (Boolean) +- **omitted** (Boolean) +- **required** (Boolean) +- **validations** (List of String) + + +### Nested Schema for `field.items` + +Required: + +- **link_type** (String) +- **type** (String) + +Optional: + +- **validations** (List of String) + + diff --git a/docs/resources/entry.md b/docs/resources/entry.md new file mode 100644 index 0000000..165a9ca --- /dev/null +++ b/docs/resources/entry.md @@ -0,0 +1,67 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "contentful_entry Resource - terraform-provider-contentful" +subcategory: "" +description: |- + +--- + +# contentful_entry (Resource) + + + +## Example Usage + +```terraform +resource "contentful_entry" "example_entry" { + entry_id = "mytestentry" + space_id = "space-id" + contenttype_id = "type-id" + locale = "en-US" + field { + id = "field1" + content = "Hello, World!" + locale = "en-US" + } + field { + id = "field2" + content = "Lettuce is healthy!" + locale = "en-US" + } + published = false + archived = false + depends_on = [contentful_contenttype.mycontenttype] +} +``` + + +## Schema + +### Required + +- **archived** (Boolean) +- **contenttype_id** (String) +- **entry_id** (String) +- **field** (Block List, Min: 1) (see [below for nested schema](#nestedblock--field)) +- **locale** (String) +- **published** (Boolean) +- **space_id** (String) + +### Optional + +- **id** (String) The ID of this resource. + +### Read-Only + +- **version** (Number) + + +### Nested Schema for `field` + +Required: + +- **content** (String) +- **id** (String) The ID of this resource. +- **locale** (String) + + diff --git a/docs/resources/environment.md b/docs/resources/environment.md new file mode 100644 index 0000000..c016889 --- /dev/null +++ b/docs/resources/environment.md @@ -0,0 +1,38 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "contentful_environment Resource - terraform-provider-contentful" +subcategory: "" +description: |- + +--- + +# contentful_environment (Resource) + + + +## Example Usage + +```terraform +resource "contentful_environment" "example_environment" { + space_id = "spaced-id" + name = "environment-name" +} +``` + + +## Schema + +### Required + +- **name** (String) +- **space_id** (String) + +### Optional + +- **id** (String) The ID of this resource. + +### Read-Only + +- **version** (Number) + + diff --git a/docs/resources/locale.md b/docs/resources/locale.md new file mode 100644 index 0000000..a199bd6 --- /dev/null +++ b/docs/resources/locale.md @@ -0,0 +1,49 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "contentful_locale Resource - terraform-provider-contentful" +subcategory: "" +description: |- + +--- + +# contentful_locale (Resource) + + + +## Example Usage + +```terraform +resource "contentful_locale" "example_locale" { + space_id = "spaced-id" + + name = "locale-name" + code = "de" + fallback_code = "en-US" + optional = false + cda = false + cma = true +} +``` + + +## Schema + +### Required + +- **code** (String) +- **name** (String) +- **space_id** (String) + +### Optional + +- **cda** (Boolean) +- **cma** (Boolean) +- **fallback_code** (String) +- **id** (String) The ID of this resource. +- **optional** (Boolean) + +### Read-Only + +- **version** (Number) + + diff --git a/docs/resources/space.md b/docs/resources/space.md new file mode 100644 index 0000000..23d9686 --- /dev/null +++ b/docs/resources/space.md @@ -0,0 +1,37 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "contentful_space Resource - terraform-provider-contentful" +subcategory: "" +description: |- + +--- + +# contentful_space (Resource) + + + +## Example Usage + +```terraform +resource "contentful_space" "example_space" { + name = "example_space_name" +} +``` + + +## Schema + +### Required + +- **name** (String) + +### Optional + +- **default_locale** (String) +- **id** (String) The ID of this resource. + +### Read-Only + +- **version** (Number) + + diff --git a/docs/resources/webhook.md b/docs/resources/webhook.md new file mode 100644 index 0000000..68f140d --- /dev/null +++ b/docs/resources/webhook.md @@ -0,0 +1,55 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "contentful_webhook Resource - terraform-provider-contentful" +subcategory: "" +description: |- + +--- + +# contentful_webhook (Resource) + + + +## Example Usage + +```terraform +resource "contentful_webhook" "example_webhook" { + space_id = "space-id" + + name = "webhook-name" + url= "https://www.example.com/test" + topics = [ + "Entry.create", + "ContentType.create", + ] + headers = { + header1 = "header1-value" + header2 = "header2-value" + } + http_basic_auth_username = "username" + http_basic_auth_password = "password" +} +``` + + +## Schema + +### Required + +- **name** (String) +- **space_id** (String) +- **topics** (List of String) +- **url** (String) + +### Optional + +- **headers** (Map of String) +- **http_basic_auth_password** (String) +- **http_basic_auth_username** (String) +- **id** (String) The ID of this resource. + +### Read-Only + +- **version** (Number) + + diff --git a/examples/resources/contentful_apikey/resource.tf b/examples/resources/contentful_apikey/resource.tf new file mode 100644 index 0000000..0f923fb --- /dev/null +++ b/examples/resources/contentful_apikey/resource.tf @@ -0,0 +1,6 @@ +resource "contentful_apikey" "myapikey" { + space_id = "space-id" + + name = "api-key-name" + description = "a-great-key" +} \ No newline at end of file diff --git a/examples/resources/contentful_asset/resource.tf b/examples/resources/contentful_asset/resource.tf new file mode 100644 index 0000000..0a5eb81 --- /dev/null +++ b/examples/resources/contentful_asset/resource.tf @@ -0,0 +1,23 @@ +resource "contentful_asset" "example_asset" { + asset_id = "test_asset" + locale = "en-US" + space_id = "space-id" + + fields { + title { + locale = "en-US" + content = "asset title" + } + description { + locale = "en-US" + content = "asset description" + } + file = { + upload = "https://images.ctfassets.net/fo9twyrwpveg/2VQx7vz73aMEYi20MMgCk0/66e502115b1f1f973a944b4bd2cc536f/IC-1H_Modern_Stack_Website.svg" + fileName = "example.jpeg" + contentType = "image/jpeg" + } + } + published = false + archived = false +} \ No newline at end of file diff --git a/examples/resources/contentful_contenttype/resource.tf b/examples/resources/contentful_contenttype/resource.tf new file mode 100644 index 0000000..f02e64e --- /dev/null +++ b/examples/resources/contentful_contenttype/resource.tf @@ -0,0 +1,30 @@ +resource "contentful_contenttype" "example_contenttype" { + space_id = "space-id" + name = "tf_linked" + description = "content type description" + display_field = "asset_field" + field { + id = "asset_field" + name = "Asset Field" + type = "Array" + items { + type = "Link" + link_type = "Asset" + } + required = true + } + field { + id = "entry_link_field" + name = "Entry Link Field" + type = "Link" + link_type = "Entry" + validations = [ + jsonencode({ + linkContentType = [ + contentful_contenttype.some_other_content_type.id + ] + }) + ] + required = false + } +} \ No newline at end of file diff --git a/examples/resources/contentful_entry/resource.tf b/examples/resources/contentful_entry/resource.tf new file mode 100644 index 0000000..315876f --- /dev/null +++ b/examples/resources/contentful_entry/resource.tf @@ -0,0 +1,19 @@ +resource "contentful_entry" "example_entry" { + entry_id = "mytestentry" + space_id = "space-id" + contenttype_id = "type-id" + locale = "en-US" + field { + id = "field1" + content = "Hello, World!" + locale = "en-US" + } + field { + id = "field2" + content = "Lettuce is healthy!" + locale = "en-US" + } + published = false + archived = false + depends_on = [contentful_contenttype.mycontenttype] +} \ No newline at end of file diff --git a/examples/resources/contentful_environment/resource.tf b/examples/resources/contentful_environment/resource.tf new file mode 100644 index 0000000..a84b097 --- /dev/null +++ b/examples/resources/contentful_environment/resource.tf @@ -0,0 +1,4 @@ +resource "contentful_environment" "example_environment" { + space_id = "spaced-id" + name = "environment-name" +} \ No newline at end of file diff --git a/examples/resources/contentful_locale/resource.tf b/examples/resources/contentful_locale/resource.tf new file mode 100644 index 0000000..896f3fb --- /dev/null +++ b/examples/resources/contentful_locale/resource.tf @@ -0,0 +1,10 @@ +resource "contentful_locale" "example_locale" { + space_id = "spaced-id" + + name = "locale-name" + code = "de" + fallback_code = "en-US" + optional = false + cda = false + cma = true +} \ No newline at end of file diff --git a/examples/resources/contentful_space/resource.tf b/examples/resources/contentful_space/resource.tf new file mode 100644 index 0000000..7c3568e --- /dev/null +++ b/examples/resources/contentful_space/resource.tf @@ -0,0 +1,3 @@ +resource "contentful_space" "example_space" { + name = "example_space_name" +} \ No newline at end of file diff --git a/examples/resources/contentful_webhook/resource.tf b/examples/resources/contentful_webhook/resource.tf new file mode 100644 index 0000000..e4fcce1 --- /dev/null +++ b/examples/resources/contentful_webhook/resource.tf @@ -0,0 +1,16 @@ +resource "contentful_webhook" "example_webhook" { + space_id = "space-id" + + name = "webhook-name" + url= "https://www.example.com/test" + topics = [ + "Entry.create", + "ContentType.create", + ] + headers = { + header1 = "header1-value" + header2 = "header2-value" + } + http_basic_auth_username = "username" + http_basic_auth_password = "password" +} \ No newline at end of file From b639dfad745807a9a717409c592796eaf219c05f Mon Sep 17 00:00:00 2001 From: demeyerthom Date: Fri, 11 Aug 2023 09:14:53 +0000 Subject: [PATCH 139/192] Synchronized project metafiles from labd/.github-private --- .github/CODEOWNERS | 1 + .github/CODE_OF_CONDUCT.md | 128 ++++++++++++++++++++++ .github/FUNDING.yml | 2 + .github/ISSUE_TEMPLATE/bug-report.md | 8 ++ .github/ISSUE_TEMPLATE/config.yml | 1 + .github/ISSUE_TEMPLATE/feature-request.md | 8 ++ .github/ISSUE_TEMPLATE/support-request.md | 8 ++ .github/pull-request-template.md | 27 +++++ .github/workflows/triage.yaml | 27 +++++ 9 files changed, 210 insertions(+) create mode 100644 .github/CODEOWNERS create mode 100644 .github/CODE_OF_CONDUCT.md create mode 100644 .github/FUNDING.yml create mode 100644 .github/ISSUE_TEMPLATE/bug-report.md create mode 100644 .github/ISSUE_TEMPLATE/config.yml create mode 100644 .github/ISSUE_TEMPLATE/feature-request.md create mode 100644 .github/ISSUE_TEMPLATE/support-request.md create mode 100644 .github/pull-request-template.md create mode 100644 .github/workflows/triage.yaml diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..00c946f --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +* @labd/go diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..18c9147 --- /dev/null +++ b/.github/CODE_OF_CONDUCT.md @@ -0,0 +1,128 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, religion, or sexual identity +and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the + overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or + advances of any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email + address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +. +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series +of actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or +permanent ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within +the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.0, available at +https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. + +Community Impact Guidelines were inspired by [Mozilla's code of conduct +enforcement ladder](https://github.com/mozilla/diversity). + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see the FAQ at +https://www.contributor-covenant.org/faq. Translations are available at +https://www.contributor-covenant.org/translations. diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..66c7a63 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,2 @@ +# These are supported funding model platform +github: [labd] diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/.github/ISSUE_TEMPLATE/bug-report.md new file mode 100644 index 0000000..4a6f11f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug-report.md @@ -0,0 +1,8 @@ +--- +name: Bug report +about: When you are running into an issue +title: '' +labels: bug, triage +assignees: '' + +--- diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..3ba13e0 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1 @@ +blank_issues_enabled: false diff --git a/.github/ISSUE_TEMPLATE/feature-request.md b/.github/ISSUE_TEMPLATE/feature-request.md new file mode 100644 index 0000000..090c4a9 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature-request.md @@ -0,0 +1,8 @@ +--- +name: Feature request +about: When you are missing a specific feature +title: '' +labels: enhancement, triage +assignees: '' + +--- diff --git a/.github/ISSUE_TEMPLATE/support-request.md b/.github/ISSUE_TEMPLATE/support-request.md new file mode 100644 index 0000000..ccb48bd --- /dev/null +++ b/.github/ISSUE_TEMPLATE/support-request.md @@ -0,0 +1,8 @@ +--- +name: Support request +about: When you have a generic question +title: '' +labels: question, triage +assignees: '' + +--- diff --git a/.github/pull-request-template.md b/.github/pull-request-template.md new file mode 100644 index 0000000..4b4165c --- /dev/null +++ b/.github/pull-request-template.md @@ -0,0 +1,27 @@ + + + + +Fixes # + +### NEW FEATURES | UPGRADE NOTES | ENHANCEMENTS | BUG FIXES | EXPERIMENTS + + + +- diff --git a/.github/workflows/triage.yaml b/.github/workflows/triage.yaml new file mode 100644 index 0000000..e5a0e40 --- /dev/null +++ b/.github/workflows/triage.yaml @@ -0,0 +1,27 @@ +name: Triage + +on: + pull_request: + types: + - opened + issues: + types: + - opened + +jobs: + add_to_project: + name: Push issue or PR to board + runs-on: ubuntu-latest + steps: + - name: get app token + id: get-app-token + uses: labd/action-gh-app-token@main + with: + app-id: ${{ secrets.RD_APP_ID }} + private-key: ${{ secrets.RD_APP_PRIVATE_KEY }} + installation-id: ${{ secrets.RD_APP_INSTALLATION_ID }} + - name: set to project board + uses: actions/add-to-project@v0.5.0 + with: + project-url: https://github.com/orgs/labd/projects/3 + github-token: ${{ steps.get-app-token.outputs.app-token }} From a1e4ba576efaefe8824f7180754dcc7423127502 Mon Sep 17 00:00:00 2001 From: "labd-project-manager[bot]" <141430439+labd-project-manager[bot]@users.noreply.github.com> Date: Fri, 1 Sep 2023 11:51:02 +0000 Subject: [PATCH 140/192] =?UTF-8?q?=F0=9F=94=84=20synced=20local=20'.githu?= =?UTF-8?q?b/'=20with=20remote=20'projects/go/.github'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/triage.yaml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/triage.yaml b/.github/workflows/triage.yaml index e5a0e40..6a30980 100644 --- a/.github/workflows/triage.yaml +++ b/.github/workflows/triage.yaml @@ -1,9 +1,6 @@ name: Triage on: - pull_request: - types: - - opened issues: types: - opened From 5aff3bbbcd3f31e52b1a5173c0fcc31340209195 Mon Sep 17 00:00:00 2001 From: Thomas De Meyer Date: Fri, 15 Sep 2023 14:53:39 +0200 Subject: [PATCH 141/192] Minor cleanup --- .gitignore | 3 +- contentful/contentful_go_.txt | 63 ----------------------------------- 2 files changed, 2 insertions(+), 64 deletions(-) delete mode 100644 contentful/contentful_go_.txt diff --git a/.gitignore b/.gitignore index 42d73fc..897eeb6 100644 --- a/.gitignore +++ b/.gitignore @@ -15,4 +15,5 @@ crash.log local/ !/local/*.example -vendor/ \ No newline at end of file +vendor/ +coverage.out diff --git a/contentful/contentful_go_.txt b/contentful/contentful_go_.txt deleted file mode 100644 index 5cd95f7..0000000 --- a/contentful/contentful_go_.txt +++ /dev/null @@ -1,63 +0,0 @@ -To make uploads resource work, the do function in the contentful go sdk -needs to be edited. This method will return an error containing the -response body. This is not included in the official repo, because this -is a temporary (and an ugly) fix. - -func (c *Client) do(req *http.Request, v interface{}) error { - if c.Debug == true { - command, _ := http2curl.GetCurlCommand(req) - fmt.Println(command) - } - - res, err := c.client.Do(req) - if err != nil { - return err - } - - if res.StatusCode >= 200 && res.StatusCode < 400 { - // Upload/Create Resource response cannot be decoded - if c.api == "URC" && req.Method == "POST" { - // Nulpointer workaround, set response as error and catch in service - buf := new(bytes.Buffer) - buf.ReadFrom(res.Body) - err = errors.New(buf.String()) - defer res.Body.Close() - return err - } else { - if v != nil { - defer res.Body.Close() - err = json.NewDecoder(res.Body).Decode(v) - if err != nil { - return err - } - } - } - - return nil - } - - // parse api response - apiError := c.handleError(req, res) - - // return apiError if it is not rate limit error - if _, ok := apiError.(RateLimitExceededError); !ok { - return apiError - } - - resetHeader := res.Header.Get("x-contentful-ratelimit-reset") - - // return apiError if Ratelimit-Reset header is not presented - if resetHeader == "" { - return apiError - } - - // wait X-Contentful-Ratelimit-Reset amount of seconds - waitSeconds, err := strconv.Atoi(resetHeader) - if err != nil { - return apiError - } - - time.Sleep(time.Second * time.Duration(waitSeconds)) - - return c.do(req, v) -} \ No newline at end of file From 1b86413025bc95284521b8c2a889f87712dbd370 Mon Sep 17 00:00:00 2001 From: Thomas De Meyer Date: Fri, 15 Sep 2023 14:57:10 +0200 Subject: [PATCH 142/192] Added changie, updated docs, updated to go 1.21 --- .changes/header.tpl.md | 6 + .changes/unreleased/.gitkeep | 0 .changes/v0.3.1.md | 24 + .changie.yaml | 26 + .github/workflows/go.yml | 53 -- .../workflows/{release.yml => release.yaml} | 18 +- .github/workflows/tests.yaml | 49 ++ .goreleaser.yml | 52 +- CHANGELOG.md | 8 + docs/index.md | 4 +- docs/resources/apikey.md | 16 +- docs/resources/asset.md | 88 ++- docs/resources/contenttype.md | 47 +- docs/resources/entry.md | 46 +- docs/resources/environment.md | 15 +- docs/resources/locale.md | 30 +- docs/resources/space.md | 10 +- docs/resources/webhook.md | 22 +- .../resources/contentful_apikey/resource.tf | 2 +- .../resources/contentful_asset/resource.tf | 12 +- .../contentful_contenttype/resource.tf | 2 +- .../resources/contentful_entry/resource.tf | 18 +- .../contentful_environment/resource.tf | 2 +- .../resources/contentful_locale/resource.tf | 10 +- .../resources/contentful_webhook/resource.tf | 2 +- go.mod | 124 +-- go.sum | 722 ++++++------------ main.go | 11 + tools.go | 10 + 29 files changed, 639 insertions(+), 790 deletions(-) create mode 100644 .changes/header.tpl.md create mode 100644 .changes/unreleased/.gitkeep create mode 100644 .changes/v0.3.1.md create mode 100644 .changie.yaml delete mode 100644 .github/workflows/go.yml rename .github/workflows/{release.yml => release.yaml} (77%) create mode 100644 .github/workflows/tests.yaml create mode 100644 tools.go diff --git a/.changes/header.tpl.md b/.changes/header.tpl.md new file mode 100644 index 0000000..df8faa7 --- /dev/null +++ b/.changes/header.tpl.md @@ -0,0 +1,6 @@ +# Changelog +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), +and is generated by [Changie](https://github.com/miniscruff/changie). diff --git a/.changes/unreleased/.gitkeep b/.changes/unreleased/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/.changes/v0.3.1.md b/.changes/v0.3.1.md new file mode 100644 index 0000000..a19058c --- /dev/null +++ b/.changes/v0.3.1.md @@ -0,0 +1,24 @@ +0.3.1 (2021-04-30) +================== +# Fixes + +* Fixed a bug causing validations in fields to not be saved properly to the models + +0.3.0 (2021-04-29) +================== +Re-release of 0.1.0 to fix registry. +# Features + +Create, update and delete Contentful resources: +- [x] Spaces +- [x] Content Types +- [x] API Keys +- [x] Webhooks +- [x] Locales +- [x] Environments +- [x] Entries +- [x] Assets + +0.1.0 (2020-10-26) +================== +Initial release \ No newline at end of file diff --git a/.changie.yaml b/.changie.yaml new file mode 100644 index 0000000..906d495 --- /dev/null +++ b/.changie.yaml @@ -0,0 +1,26 @@ +changesDir: .changes +unreleasedDir: unreleased +headerPath: header.tpl.md +changelogPath: CHANGELOG.md +versionExt: md +versionFormat: '## {{.Version}} - {{.Time.Format "2006-01-02"}}' +kindFormat: '### {{.Kind}}' +changeFormat: '* {{.Body}}' +kinds: +- label: Added + auto: minor +- label: Changed + auto: major +- label: Deprecated + auto: minor +- label: Removed + auto: major +- label: Fixed + auto: patch +- label: Security + auto: patch +newlines: + afterChangelogHeader: 1 + beforeChangelogVersion: 1 + endOfVersion: 1 +envPrefix: CHANGIE_ diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml deleted file mode 100644 index cc0cc1f..0000000 --- a/.github/workflows/go.yml +++ /dev/null @@ -1,53 +0,0 @@ -name: Go - -on: - push: - branches: [ master ] - pull_request: - branches: [ master ] - -jobs: - - build: - name: Build - runs-on: ubuntu-latest - steps: - - name: Set up Go 1.17.6 - uses: actions/setup-go@v1 - with: - go-version: 1.17.6 - id: go - - name: Check out code into the Go module directory - uses: actions/checkout@v2 - - name: Get dependencies - run: | - go get -v -t -d ./... - if [ -f Gopkg.toml ]; then - curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh - dep ensure - fi - - name: Build - run: go build -v . - test: - name: Test - runs-on: ubuntu-latest - needs: [build] - steps: - - name: Set up Go 1.17.6 - uses: actions/setup-go@v1 - with: - go-version: 1.17.6 - id: go - - name: Check out code into the Go module directory - uses: actions/checkout@v2 - - name: Install dependencies - run: go get ./contentful - - name: Run tests - run: go test -race -coverprofile=coverage.txt -covermode=atomic -coverpkg=./contentful -v ./contentful - env: - TF_ACC: 1 - CONTENTFUL_ORGANIZATION_ID: ${{ secrets.CONTENTFUL_ORGANIZATION_ID }} - CONTENTFUL_MANAGEMENT_TOKEN: ${{ secrets.CONTENTFUL_MANAGEMENT_TOKEN }} - SPACE_ID: ${{ secrets.SPACE_ID }} - - name: Upload to codecov - uses: codecov/codecov-action@v1.0.6 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yaml similarity index 77% rename from .github/workflows/release.yml rename to .github/workflows/release.yaml index a21aa74..612af53 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yaml @@ -1,26 +1,28 @@ name: release on: - push: - tags: - - 'v*' + workflow_dispatch: + jobs: goreleaser: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v2 - - name: Unshallow - run: git fetch --prune --unshallow + uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Set up Go - uses: actions/setup-go@v2 + uses: actions/setup-go@v4 with: - go-version: 1.17 + go-version: "1.21" + - name: Import GPG key id: import_gpg uses: paultyng/ghaction-import-gpg@v2.1.0 env: GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} + - name: Run GoReleaser uses: goreleaser/goreleaser-action@v2 with: diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml new file mode 100644 index 0000000..abbc635 --- /dev/null +++ b/.github/workflows/tests.yaml @@ -0,0 +1,49 @@ +name: Run Tests + +on: [ push ] + +jobs: + + test: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - name: Set up Go 1.21 + uses: actions/setup-go@v2 + with: + go-version: "1.21" + + - name: golangci-lint + continue-on-error: true + uses: golangci/golangci-lint-action@v3 + with: + args: --issues-exit-code=0 --timeout=5m + + - name: Run tests + run: go test -race -coverprofile=coverage.out -covermode=atomic -coverpkg=./... -v ./... + + - name: Upload to codecov + uses: codecov/codecov-action@v3 + with: + verbose: true + + changie: + runs-on: ubuntu-latest + needs: test + if: github.ref == 'refs/heads/main' && github.event_name != 'pull_request' + permissions: + contents: write + pull-requests: write + actions: write + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Prepare release + uses: labd/changie-release-action@v0.2.0 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + release-workflow: 'release.yaml' diff --git a/.goreleaser.yml b/.goreleaser.yml index fb1141f..5307fc7 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -1,34 +1,34 @@ project_name: terraform-provider-contentful builds: -- env: - # goreleaser does not work with CGO, it could also complicate - # usage by users in CI/CD systems like Terraform Cloud where - # they are unable to install libraries. - - CGO_ENABLED=0 - mod_timestamp: '{{ .CommitTimestamp }}' - flags: - - -trimpath - ldflags: - - '-s -w -X main.version={{.Version}} -X main.commit={{.Commit}}' - goos: - - freebsd - - windows - - linux - - darwin - goarch: - - amd64 - - '386' - - arm - - arm64 - ignore: - - goos: darwin - goarch: '386' - binary: '{{ .ProjectName }}_v{{ .Version }}' + - env: + # goreleaser does not work with CGO, it could also complicate + # usage by users in CI/CD systems like Terraform Cloud where + # they are unable to install libraries. + - CGO_ENABLED=0 + mod_timestamp: '{{ .CommitTimestamp }}' + flags: + - -trimpath + ldflags: + - '-s -w -X main.version={{.Version}} -X main.commit={{.ShortCommit}}' + goos: + - freebsd + - windows + - linux + - darwin + goarch: + - amd64 + - '386' + - arm + - arm64 + ignore: + - goos: darwin + goarch: '386' + binary: '{{ .ProjectName }}_v{{ .Version }}' archives: -- format: zip - name_template: '{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}' + - format: zip + name_template: '{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}' checksum: name_template: '{{ .ProjectName }}_{{ .Version }}_SHA256SUMS' diff --git a/CHANGELOG.md b/CHANGELOG.md index a19058c..7eb6901 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +# Changelog +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), +and is generated by [Changie](https://github.com/miniscruff/changie). + + 0.3.1 (2021-04-30) ================== # Fixes diff --git a/docs/index.md b/docs/index.md index bdabb85..85f8c5e 100644 --- a/docs/index.md +++ b/docs/index.md @@ -17,5 +17,5 @@ description: |- ### Required -- **cma_token** (String) The Contentful Management API token -- **organization_id** (String) The organization ID +- `cma_token` (String) The Contentful Management API token +- `organization_id` (String) The organization ID diff --git a/docs/resources/apikey.md b/docs/resources/apikey.md index a28ec1b..f847af3 100644 --- a/docs/resources/apikey.md +++ b/docs/resources/apikey.md @@ -16,7 +16,7 @@ description: |- resource "contentful_apikey" "myapikey" { space_id = "space-id" - name = "api-key-name" + name = "api-key-name" description = "a-great-key" } ``` @@ -26,17 +26,15 @@ resource "contentful_apikey" "myapikey" { ### Required -- **name** (String) -- **space_id** (String) +- `name` (String) +- `space_id` (String) ### Optional -- **description** (String) -- **id** (String) The ID of this resource. +- `description` (String) ### Read-Only -- **access_token** (String) -- **version** (Number) - - +- `access_token` (String) +- `id` (String) The ID of this resource. +- `version` (Number) diff --git a/docs/resources/asset.md b/docs/resources/asset.md index 19a8744..ebf3b77 100644 --- a/docs/resources/asset.md +++ b/docs/resources/asset.md @@ -15,26 +15,26 @@ description: |- ```terraform resource "contentful_asset" "example_asset" { asset_id = "test_asset" - locale = "en-US" + locale = "en-US" space_id = "space-id" fields { title { - locale = "en-US" + locale = "en-US" content = "asset title" } description { - locale = "en-US" + locale = "en-US" content = "asset description" } - file { - upload = "https://images.ctfassets.net/fo9twyrwpveg/2VQx7vz73aMEYi20MMgCk0/66e502115b1f1f973a944b4bd2cc536f/IC-1H_Modern_Stack_Website.svg" - file_name = "example.jpeg" - content_type = "image/jpeg" + file = { + upload = "https://images.ctfassets.net/fo9twyrwpveg/2VQx7vz73aMEYi20MMgCk0/66e502115b1f1f973a944b4bd2cc536f/IC-1H_Modern_Stack_Website.svg" + fileName = "example.jpeg" + contentType = "image/jpeg" } } published = false - archived = false + archived = false } ``` @@ -43,45 +43,77 @@ resource "contentful_asset" "example_asset" { ### Required -- **archived** (Boolean) -- **asset_id** (String) -- **fields** (Block List, Min: 1) (see [below for nested schema](#nestedblock--fields)) -- **locale** (String) -- **published** (Boolean) -- **space_id** (String) - -### Optional - -- **id** (String) The ID of this resource. +- `archived` (Boolean) +- `asset_id` (String) +- `fields` (Block List, Min: 1) (see [below for nested schema](#nestedblock--fields)) +- `locale` (String) +- `published` (Boolean) +- `space_id` (String) ### Read-Only -- **version** (Number) +- `id` (String) The ID of this resource. +- `version` (Number) ### Nested Schema for `fields` Required: -- **description** (Block List, Min: 1) (see [below for nested schema](#nestedblock--fields--description)) -- **file** (Map of String) -- **title** (Block List, Min: 1) (see [below for nested schema](#nestedblock--fields--title)) +- `description` (Block List, Min: 1) (see [below for nested schema](#nestedblock--fields--description)) +- `file` (Block List, Min: 1, Max: 1) (see [below for nested schema](#nestedblock--fields--file)) +- `title` (Block List, Min: 1) (see [below for nested schema](#nestedblock--fields--title)) ### Nested Schema for `fields.description` Required: -- **content** (String) -- **locale** (String) +- `content` (String) +- `locale` (String) - -### Nested Schema for `fields.title` + +### Nested Schema for `fields.file` + +Required: + +- `content_type` (String) +- `file_name` (String) +- `upload` (String) + +Optional: + +- `details` (Block Set) (see [below for nested schema](#nestedblock--fields--file--details)) + +Read-Only: + +- `upload_from` (String) +- `url` (String) + + +### Nested Schema for `fields.file.details` Required: -- **content** (String) -- **locale** (String) +- `image` (Block Set, Min: 1) (see [below for nested schema](#nestedblock--fields--file--details--image)) +- `size` (Number) + +### Nested Schema for `fields.file.details.image` + +Required: + +- `height` (Number) +- `width` (Number) + + + + + +### Nested Schema for `fields.title` + +Required: +- `content` (String) +- `locale` (String) diff --git a/docs/resources/contenttype.md b/docs/resources/contenttype.md index 67ef6d8..73317da 100644 --- a/docs/resources/contenttype.md +++ b/docs/resources/contenttype.md @@ -14,7 +14,7 @@ description: |- ```terraform resource "contentful_contenttype" "example_contenttype" { - space_id = "space-id" + space_id = "space-id" name = "tf_linked" description = "content type description" display_field = "asset_field" @@ -50,49 +50,50 @@ resource "contentful_contenttype" "example_contenttype" { ### Required -- **display_field** (String) -- **field** (Block List, Min: 1) (see [below for nested schema](#nestedblock--field)) -- **name** (String) -- **space_id** (String) +- `display_field` (String) +- `field` (Block List, Min: 1) (see [below for nested schema](#nestedblock--field)) +- `name` (String) +- `space_id` (String) ### Optional -- **description** (String) -- **id** (String) The ID of this resource. +- `description` (String) ### Read-Only -- **version** (Number) +- `id` (String) The ID of this resource. +- `version` (Number) ### Nested Schema for `field` Required: -- **id** (String) The ID of this resource. -- **name** (String) -- **type** (String) +- `name` (String) +- `type` (String) Optional: -- **disabled** (Boolean) -- **items** (Block List, Max: 1) (see [below for nested schema](#nestedblock--field--items)) -- **link_type** (String) -- **localized** (Boolean) -- **omitted** (Boolean) -- **required** (Boolean) -- **validations** (List of String) +- `disabled` (Boolean) +- `items` (Block List, Max: 1) (see [below for nested schema](#nestedblock--field--items)) +- `link_type` (String) +- `localized` (Boolean) +- `omitted` (Boolean) +- `required` (Boolean) +- `validations` (List of String) + +Read-Only: + +- `id` (String) The ID of this resource. ### Nested Schema for `field.items` Required: -- **link_type** (String) -- **type** (String) +- `link_type` (String) +- `type` (String) Optional: -- **validations** (List of String) - - +- `validations` (List of String) diff --git a/docs/resources/entry.md b/docs/resources/entry.md index 165a9ca..ba7b808 100644 --- a/docs/resources/entry.md +++ b/docs/resources/entry.md @@ -14,22 +14,22 @@ description: |- ```terraform resource "contentful_entry" "example_entry" { - entry_id = "mytestentry" - space_id = "space-id" + entry_id = "mytestentry" + space_id = "space-id" contenttype_id = "type-id" - locale = "en-US" + locale = "en-US" field { - id = "field1" + id = "field1" content = "Hello, World!" - locale = "en-US" + locale = "en-US" } field { - id = "field2" + id = "field2" content = "Lettuce is healthy!" - locale = "en-US" + locale = "en-US" } - published = false - archived = false + published = false + archived = false depends_on = [contentful_contenttype.mycontenttype] } ``` @@ -39,29 +39,27 @@ resource "contentful_entry" "example_entry" { ### Required -- **archived** (Boolean) -- **contenttype_id** (String) -- **entry_id** (String) -- **field** (Block List, Min: 1) (see [below for nested schema](#nestedblock--field)) -- **locale** (String) -- **published** (Boolean) -- **space_id** (String) - -### Optional - -- **id** (String) The ID of this resource. +- `archived` (Boolean) +- `contenttype_id` (String) +- `entry_id` (String) +- `field` (Block List, Min: 1) (see [below for nested schema](#nestedblock--field)) +- `locale` (String) +- `published` (Boolean) +- `space_id` (String) ### Read-Only -- **version** (Number) +- `id` (String) The ID of this resource. +- `version` (Number) ### Nested Schema for `field` Required: -- **content** (String) -- **id** (String) The ID of this resource. -- **locale** (String) +- `content` (String) +- `locale` (String) +Read-Only: +- `id` (String) The ID of this resource. diff --git a/docs/resources/environment.md b/docs/resources/environment.md index c016889..465439a 100644 --- a/docs/resources/environment.md +++ b/docs/resources/environment.md @@ -15,7 +15,7 @@ description: |- ```terraform resource "contentful_environment" "example_environment" { space_id = "spaced-id" - name = "environment-name" + name = "environment-name" } ``` @@ -24,15 +24,10 @@ resource "contentful_environment" "example_environment" { ### Required -- **name** (String) -- **space_id** (String) - -### Optional - -- **id** (String) The ID of this resource. +- `name` (String) +- `space_id` (String) ### Read-Only -- **version** (Number) - - +- `id` (String) The ID of this resource. +- `version` (Number) diff --git a/docs/resources/locale.md b/docs/resources/locale.md index a199bd6..f27d118 100644 --- a/docs/resources/locale.md +++ b/docs/resources/locale.md @@ -16,12 +16,12 @@ description: |- resource "contentful_locale" "example_locale" { space_id = "spaced-id" - name = "locale-name" - code = "de" + name = "locale-name" + code = "de" fallback_code = "en-US" - optional = false - cda = false - cma = true + optional = false + cda = false + cma = true } ``` @@ -30,20 +30,18 @@ resource "contentful_locale" "example_locale" { ### Required -- **code** (String) -- **name** (String) -- **space_id** (String) +- `code` (String) +- `name` (String) +- `space_id` (String) ### Optional -- **cda** (Boolean) -- **cma** (Boolean) -- **fallback_code** (String) -- **id** (String) The ID of this resource. -- **optional** (Boolean) +- `cda` (Boolean) +- `cma` (Boolean) +- `fallback_code` (String) +- `optional` (Boolean) ### Read-Only -- **version** (Number) - - +- `id` (String) The ID of this resource. +- `version` (Number) diff --git a/docs/resources/space.md b/docs/resources/space.md index 23d9686..75eca53 100644 --- a/docs/resources/space.md +++ b/docs/resources/space.md @@ -23,15 +23,13 @@ resource "contentful_space" "example_space" { ### Required -- **name** (String) +- `name` (String) ### Optional -- **default_locale** (String) -- **id** (String) The ID of this resource. +- `default_locale` (String) ### Read-Only -- **version** (Number) - - +- `id` (String) The ID of this resource. +- `version` (Number) diff --git a/docs/resources/webhook.md b/docs/resources/webhook.md index db2e410..d982e4b 100644 --- a/docs/resources/webhook.md +++ b/docs/resources/webhook.md @@ -17,7 +17,7 @@ resource "contentful_webhook" "example_webhook" { space_id = "space-id" name = "webhook-name" - url = "https://www.example.com/test" + url = "https://www.example.com/test" topics = [ "Entry.create", "ContentType.create", @@ -36,20 +36,18 @@ resource "contentful_webhook" "example_webhook" { ### Required -- **name** (String) -- **space_id** (String) -- **topics** (List of String) -- **url** (String) +- `name` (String) +- `space_id` (String) +- `topics` (List of String) +- `url` (String) ### Optional -- **headers** (Map of String) -- **http_basic_auth_password** (String) -- **http_basic_auth_username** (String) -- **id** (String) The ID of this resource. +- `headers` (Map of String) +- `http_basic_auth_password` (String) +- `http_basic_auth_username` (String) ### Read-Only -- **version** (Number) - - +- `id` (String) The ID of this resource. +- `version` (Number) diff --git a/examples/resources/contentful_apikey/resource.tf b/examples/resources/contentful_apikey/resource.tf index 0f923fb..7b00576 100644 --- a/examples/resources/contentful_apikey/resource.tf +++ b/examples/resources/contentful_apikey/resource.tf @@ -1,6 +1,6 @@ resource "contentful_apikey" "myapikey" { space_id = "space-id" - name = "api-key-name" + name = "api-key-name" description = "a-great-key" } \ No newline at end of file diff --git a/examples/resources/contentful_asset/resource.tf b/examples/resources/contentful_asset/resource.tf index 0a5eb81..f7466aa 100644 --- a/examples/resources/contentful_asset/resource.tf +++ b/examples/resources/contentful_asset/resource.tf @@ -1,23 +1,23 @@ resource "contentful_asset" "example_asset" { asset_id = "test_asset" - locale = "en-US" + locale = "en-US" space_id = "space-id" fields { title { - locale = "en-US" + locale = "en-US" content = "asset title" } description { - locale = "en-US" + locale = "en-US" content = "asset description" } file = { - upload = "https://images.ctfassets.net/fo9twyrwpveg/2VQx7vz73aMEYi20MMgCk0/66e502115b1f1f973a944b4bd2cc536f/IC-1H_Modern_Stack_Website.svg" - fileName = "example.jpeg" + upload = "https://images.ctfassets.net/fo9twyrwpveg/2VQx7vz73aMEYi20MMgCk0/66e502115b1f1f973a944b4bd2cc536f/IC-1H_Modern_Stack_Website.svg" + fileName = "example.jpeg" contentType = "image/jpeg" } } published = false - archived = false + archived = false } \ No newline at end of file diff --git a/examples/resources/contentful_contenttype/resource.tf b/examples/resources/contentful_contenttype/resource.tf index f02e64e..f3c0604 100644 --- a/examples/resources/contentful_contenttype/resource.tf +++ b/examples/resources/contentful_contenttype/resource.tf @@ -1,5 +1,5 @@ resource "contentful_contenttype" "example_contenttype" { - space_id = "space-id" + space_id = "space-id" name = "tf_linked" description = "content type description" display_field = "asset_field" diff --git a/examples/resources/contentful_entry/resource.tf b/examples/resources/contentful_entry/resource.tf index 315876f..c1ebf51 100644 --- a/examples/resources/contentful_entry/resource.tf +++ b/examples/resources/contentful_entry/resource.tf @@ -1,19 +1,19 @@ resource "contentful_entry" "example_entry" { - entry_id = "mytestentry" - space_id = "space-id" + entry_id = "mytestentry" + space_id = "space-id" contenttype_id = "type-id" - locale = "en-US" + locale = "en-US" field { - id = "field1" + id = "field1" content = "Hello, World!" - locale = "en-US" + locale = "en-US" } field { - id = "field2" + id = "field2" content = "Lettuce is healthy!" - locale = "en-US" + locale = "en-US" } - published = false - archived = false + published = false + archived = false depends_on = [contentful_contenttype.mycontenttype] } \ No newline at end of file diff --git a/examples/resources/contentful_environment/resource.tf b/examples/resources/contentful_environment/resource.tf index a84b097..336b3b6 100644 --- a/examples/resources/contentful_environment/resource.tf +++ b/examples/resources/contentful_environment/resource.tf @@ -1,4 +1,4 @@ resource "contentful_environment" "example_environment" { space_id = "spaced-id" - name = "environment-name" + name = "environment-name" } \ No newline at end of file diff --git a/examples/resources/contentful_locale/resource.tf b/examples/resources/contentful_locale/resource.tf index 896f3fb..e42a48c 100644 --- a/examples/resources/contentful_locale/resource.tf +++ b/examples/resources/contentful_locale/resource.tf @@ -1,10 +1,10 @@ resource "contentful_locale" "example_locale" { space_id = "spaced-id" - name = "locale-name" - code = "de" + name = "locale-name" + code = "de" fallback_code = "en-US" - optional = false - cda = false - cma = true + optional = false + cda = false + cma = true } \ No newline at end of file diff --git a/examples/resources/contentful_webhook/resource.tf b/examples/resources/contentful_webhook/resource.tf index e4fcce1..f95d46e 100644 --- a/examples/resources/contentful_webhook/resource.tf +++ b/examples/resources/contentful_webhook/resource.tf @@ -2,7 +2,7 @@ resource "contentful_webhook" "example_webhook" { space_id = "space-id" name = "webhook-name" - url= "https://www.example.com/test" + url = "https://www.example.com/test" topics = [ "Entry.create", "ContentType.create", diff --git a/go.mod b/go.mod index 5b57b60..105f009 100644 --- a/go.mod +++ b/go.mod @@ -1,69 +1,77 @@ module github.com/labd/terraform-provider-contentful -go 1.17 +go 1.21 -require github.com/labd/contentful-go v0.5.0 +require ( + github.com/hashicorp/terraform-plugin-docs v0.16.0 + github.com/labd/contentful-go v0.5.3 +) + +require ( + github.com/Masterminds/goutils v1.1.1 // indirect + github.com/Masterminds/semver/v3 v3.2.1 // indirect + github.com/Masterminds/sprig/v3 v3.2.3 // indirect + github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 // indirect + github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect + github.com/armon/go-radix v1.0.0 // indirect + github.com/bgentry/speakeasy v0.1.0 // indirect + github.com/cloudflare/circl v1.3.3 // indirect + github.com/google/uuid v1.3.1 // indirect + github.com/hashicorp/hc-install v0.6.0 // indirect + github.com/hashicorp/terraform-plugin-log v0.9.0 // indirect + github.com/hashicorp/terraform-registry-address v0.2.2 // indirect + github.com/hashicorp/terraform-svchost v0.1.1 // indirect + github.com/huandu/xstrings v1.4.0 // indirect + github.com/imdario/mergo v0.3.16 // indirect + github.com/mitchellh/cli v1.1.5 // indirect + github.com/posener/complete v1.2.3 // indirect + github.com/russross/blackfriday v1.6.0 // indirect + github.com/shopspring/decimal v1.3.1 // indirect + github.com/spf13/cast v1.5.1 // indirect + github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect + github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect + golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230913181813-007df8e322eb // indirect +) require ( - cloud.google.com/go v0.61.0 // indirect - cloud.google.com/go/storage v1.10.0 // indirect - github.com/agext/levenshtein v1.2.2 // indirect - github.com/apparentlymart/go-cidr v1.0.1 // indirect - github.com/apparentlymart/go-textseg v1.0.0 // indirect - github.com/aws/aws-sdk-go v1.25.3 // indirect - github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/fatih/color v1.7.0 // indirect - github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect - github.com/golang/protobuf v1.4.2 // indirect - github.com/google/go-cmp v0.5.2 // indirect - github.com/googleapis/gax-go/v2 v2.0.5 // indirect - github.com/hashicorp/errwrap v1.0.0 // indirect + github.com/agext/levenshtein v1.2.3 // indirect + github.com/fatih/color v1.15.0 // indirect + github.com/golang/protobuf v1.5.3 // indirect + github.com/google/go-cmp v0.5.9 // indirect + github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-checkpoint v0.5.0 // indirect - github.com/hashicorp/go-cleanhttp v0.5.1 // indirect + github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 // indirect - github.com/hashicorp/go-getter v1.5.0 // indirect - github.com/hashicorp/go-hclog v0.15.0 // indirect - github.com/hashicorp/go-multierror v1.0.0 // indirect - github.com/hashicorp/go-plugin v1.4.0 // indirect - github.com/hashicorp/go-safetemp v1.0.0 // indirect - github.com/hashicorp/go-uuid v1.0.1 // indirect - github.com/hashicorp/go-version v1.2.1 // indirect - github.com/hashicorp/hcl/v2 v2.3.0 // indirect + github.com/hashicorp/go-hclog v1.5.0 // indirect + github.com/hashicorp/go-multierror v1.1.1 // indirect + github.com/hashicorp/go-plugin v1.5.1 // indirect + github.com/hashicorp/go-uuid v1.0.3 // indirect + github.com/hashicorp/go-version v1.6.0 // indirect + github.com/hashicorp/hcl/v2 v2.18.0 // indirect github.com/hashicorp/logutils v1.0.0 // indirect - github.com/hashicorp/terraform-exec v0.13.0 // indirect - github.com/hashicorp/terraform-json v0.8.0 // indirect - github.com/hashicorp/terraform-plugin-go v0.2.1 // indirect - github.com/hashicorp/terraform-plugin-sdk/v2 v2.4.3 - github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d // indirect - github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af // indirect - github.com/jstemmer/go-junit-report v0.9.1 // indirect - github.com/mattn/go-colorable v0.1.4 // indirect - github.com/mattn/go-isatty v0.0.10 // indirect - github.com/mitchellh/copystructure v1.0.0 // indirect - github.com/mitchellh/go-homedir v1.1.0 // indirect - github.com/mitchellh/go-testing-interface v1.0.4 // indirect - github.com/mitchellh/go-wordwrap v1.0.0 // indirect - github.com/mitchellh/mapstructure v1.1.2 // indirect - github.com/mitchellh/reflectwalk v1.0.1 // indirect - github.com/oklog/run v1.0.0 // indirect - github.com/ulikunitz/xz v0.5.8 // indirect + github.com/hashicorp/terraform-exec v0.19.0 // indirect + github.com/hashicorp/terraform-json v0.17.1 // indirect + github.com/hashicorp/terraform-plugin-go v0.19.0 // indirect + github.com/hashicorp/terraform-plugin-sdk/v2 v2.29.0 + github.com/hashicorp/yamux v0.1.1 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.19 // indirect + github.com/mitchellh/copystructure v1.2.0 // indirect + github.com/mitchellh/go-testing-interface v1.14.1 // indirect + github.com/mitchellh/go-wordwrap v1.0.1 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/mitchellh/reflectwalk v1.0.2 // indirect + github.com/oklog/run v1.1.0 // indirect github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect - github.com/zclconf/go-cty v1.2.1 // indirect - go.opencensus.io v0.22.4 // indirect - golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 // indirect - golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect - golang.org/x/mod v0.3.0 // indirect - golang.org/x/net v0.0.0-20200707034311-ab3426394381 // indirect - golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d // indirect - golang.org/x/sys v0.0.0-20200523222454-059865788121 // indirect - golang.org/x/text v0.3.3 // indirect - golang.org/x/tools v0.0.0-20200713011307-fd294ab11aed // indirect - golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 // indirect - google.golang.org/api v0.29.0 // indirect - google.golang.org/appengine v1.6.6 // indirect - google.golang.org/genproto v0.0.0-20200711021454-869866162049 // indirect - google.golang.org/grpc v1.32.0 // indirect - google.golang.org/protobuf v1.25.0 // indirect + github.com/zclconf/go-cty v1.14.0 // indirect + golang.org/x/crypto v0.13.0 // indirect + golang.org/x/mod v0.12.0 // indirect + golang.org/x/net v0.15.0 // indirect + golang.org/x/sys v0.12.0 // indirect + golang.org/x/text v0.13.0 // indirect + google.golang.org/appengine v1.6.8 // indirect + google.golang.org/grpc v1.58.1 // indirect + google.golang.org/protobuf v1.31.0 // indirect moul.io/http2curl v1.0.1-0.20190925090545-5cd742060b0e // indirect ) diff --git a/go.sum b/go.sum index 84b9936..b675fca 100644 --- a/go.sum +++ b/go.sum @@ -1,559 +1,299 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= -cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= -cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= -cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= -cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= -cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= -cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= -cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= -cloud.google.com/go v0.61.0 h1:NLQf5e1OMspfNT1RAHOB3ublr1TW3YTXO8OiWwVjK2U= -cloud.google.com/go v0.61.0/go.mod h1:XukKJg4Y7QsUu0Hxg3qQKUWR4VuWivmyMK2+rUyxAqw= -cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= -cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= -cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= -cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= -cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= -cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= -cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= -cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= -cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= -cloud.google.com/go/storage v1.10.0 h1:STgFzyU5/8miMl0//zKh2aQeTyeaUH3WN9bSUiJ09bA= -cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -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/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-20170116200512-5312a6153412/go.mod h1:WPjqKcmVOxf0XSf3YxCJs6N6AOSrOx3obionmG7T0y0= -github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= -github.com/andybalholm/crlf v0.0.0-20171020200849-670099aa064f/go.mod h1:k8feO4+kXDxro6ErPXBRTJ/ro2mf0SsFG8s7doP9kJE= -github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= -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= -github.com/apparentlymart/go-dump v0.0.0-20190214190832-042adf3cf4a0 h1:MzVXffFUye+ZcSR6opIgz9Co7WcDx6ZcY+RjfFHoA0I= -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= +dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= +dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= +github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= +github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= +github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= +github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= +github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= +github.com/Masterminds/sprig/v3 v3.2.1/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk= +github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA= +github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM= +github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= +github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= +github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 h1:kkhsdkhsCvIsutKu5zLMgWtgh9YxGCNAw8Ad8hjwfYg= +github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= +github.com/acomagu/bufpipe v1.0.4 h1:e3H4WUzM3npvo5uv95QuJM3cQspFNtFBzvJ2oNjKIDQ= +github.com/acomagu/bufpipe v1.0.4/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4= +github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= +github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec= +github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY= +github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -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/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas= -github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4= +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/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -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/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/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA= +github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8= +github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= +github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs= +github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= 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/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg= -github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= -github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= +github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= +github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= -github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= -github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= -github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= -github.com/go-git/go-billy/v5 v5.0.0 h1:7NQHvd9FVid8VL4qVUMm8XifBK+2xCoZ2lSk0agRrHM= -github.com/go-git/go-billy/v5 v5.0.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= -github.com/go-git/go-git-fixtures/v4 v4.0.1/go.mod h1:m+ICp2rF3jDhFgEZ/8yziagdT1C+ZpZcrJjappBCDSw= -github.com/go-git/go-git/v5 v5.1.0 h1:HxJn9g/E7eYvKW3Fm7Jt4ee8LXfPOm/H1cdDu8vEssk= -github.com/go-git/go-git/v5 v5.1.0/go.mod h1:ZKfuPUoY1ZqIG4QG9BDBh3G4gLM5zvPuSJAozQrZuyM= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= +github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= +github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= +github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= +github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= +github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= +github.com/go-git/go-billy/v5 v5.4.1 h1:Uwp5tDRkPr+l/TnbHOQzp+tmJfLceOlbVucgpTz8ix4= +github.com/go-git/go-billy/v5 v5.4.1/go.mod h1:vjbugF6Fz7JIflbVpl1hJsGjSHNltrSw45YK/ukIvQg= +github.com/go-git/go-git/v5 v5.8.1 h1:Zo79E4p7TRk0xoRgMq0RShiTHGKcKI4+DI6BfJc/Q+A= +github.com/go-git/go-git/v5 v5.8.1/go.mod h1:FHFuoD6yGz5OSKEBK+aWN9Oah0q54Jxl0abmj6GnqAo= 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/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/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= -github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= -github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -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/martian/v3 v3.0.0 h1:pMen7vLs8nvgEYhywH3KDWJIJTeEr2ULsVWHWYHQyBs= -github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -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/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= +github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= +github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= 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= +github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= +github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 h1:1/D3zfFHttUKaCaGKZ/dR2roBXv0vKbSCnssIldfQdI= github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320/go.mod h1:EiZBMaudVLy8fmjf9Npq1dq9RalhveqZG5w/yz3mHWs= -github.com/hashicorp/go-getter v1.4.0/go.mod h1:7qxyCd8rBfcShwsvxgIguu4KbS3l8bUCwg2Umn7RjeY= -github.com/hashicorp/go-getter v1.5.0 h1:ciWJaeZWSMbc5OiLMpKp40MKFPqO44i0h3uyfXPBkkk= -github.com/hashicorp/go-getter v1.5.0/go.mod h1:a7z7NPPfNQpJWcn4rSWFtdrSldqLdLPEF3d8nFMsSLM= -github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI= -github.com/hashicorp/go-hclog v0.14.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= -github.com/hashicorp/go-hclog v0.15.0 h1:qMuK0wxsoW4D0ddCCYwPSTm4KQv1X1ke3WmPWZ0Mvsk= -github.com/hashicorp/go-hclog v0.15.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= -github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o= +github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c= +github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/go-plugin v1.3.0/go.mod h1:F9eH4LrE/ZsRdbwhfjs9k9HoDUwAHnYtXdgmf1AVNs0= -github.com/hashicorp/go-plugin v1.4.0 h1:b0O7rs5uiJ99Iu9HugEzsM67afboErkHUWddUSpUO3A= -github.com/hashicorp/go-plugin v1.4.0/go.mod h1:5fGEH17QVwTTcR0zV7yhDPLLmFX9YSZ38b18Udy6vYQ= -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-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= +github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= +github.com/hashicorp/go-plugin v1.5.1 h1:oGm7cWBaYIp3lJpx1RUEfLWophprE2EV/KUeqBYo+6k= +github.com/hashicorp/go-plugin v1.5.1/go.mod h1:w1sAEES3g3PuV/RzUrgow20W2uErMly84hhD3um1WL4= 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= -github.com/hashicorp/go-version v1.2.1 h1:zEfKbn2+PDgroKdiOzqiE8rsmLqU2uwi5PB5pBJ3TkI= -github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -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/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= +github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= +github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/hc-install v0.6.0 h1:fDHnU7JNFNSQebVKYhHZ0va1bC6SrPQ8fpebsvNr2w4= +github.com/hashicorp/hc-install v0.6.0/go.mod h1:10I912u3nntx9Umo1VAeYPUUuehk0aRQJYpMwbX5wQA= +github.com/hashicorp/hcl/v2 v2.18.0 h1:wYnG7Lt31t2zYkcquwgKo6MWXzRUDIeIVU5naZwHLl8= +github.com/hashicorp/hcl/v2 v2.18.0/go.mod h1:ThLC89FV4p9MPW804KVbe/cEXoQ8NZEh+JtMeeGErHE= 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/terraform-exec v0.13.0 h1:1Pth+pdWJAufJuWWjaVOVNEkoRTOjGn3hQpAqj4aPdg= -github.com/hashicorp/terraform-exec v0.13.0/go.mod h1:SGhto91bVRlgXQWcJ5znSz+29UZIa8kpBbkGwQ+g9E8= -github.com/hashicorp/terraform-json v0.8.0 h1:XObQ3PgqU52YLQKEaJ08QtUshAfN3yu4u8ebSW0vztc= -github.com/hashicorp/terraform-json v0.8.0/go.mod h1:3defM4kkMfttwiE7VakJDwCd4R+umhSQnvJwORXbprE= -github.com/hashicorp/terraform-plugin-go v0.2.1 h1:EW/R8bB2Zbkjmugzsy1d27yS8/0454b3MtYHkzOknqA= -github.com/hashicorp/terraform-plugin-go v0.2.1/go.mod h1:10V6F3taeDWVAoLlkmArKttR3IULlRWFAGtQIQTIDr4= -github.com/hashicorp/terraform-plugin-sdk/v2 v2.4.3 h1:DGnxpIYRHXQZb2TOlQ1OCEYxoRQrAcbLIcYm8kvbFuU= -github.com/hashicorp/terraform-plugin-sdk/v2 v2.4.3/go.mod h1:5wrrTcxbSaQXamCDbHZTHk6yTF9OEZaOvQ9fvLXBE3o= -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= -github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/imdario/mergo v0.3.9 h1:UauaLniWCFHWd+Jp9oCEkTBj8VO/9DKg3PV3VCNMDIg= -github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/hashicorp/terraform-exec v0.19.0 h1:FpqZ6n50Tk95mItTSS9BjeOVUb4eg81SpgVtZNNtFSM= +github.com/hashicorp/terraform-exec v0.19.0/go.mod h1:tbxUpe3JKruE9Cuf65mycSIT8KiNPZ0FkuTE3H4urQg= +github.com/hashicorp/terraform-json v0.17.1 h1:eMfvh/uWggKmY7Pmb3T85u86E2EQg6EQHgyRwf3RkyA= +github.com/hashicorp/terraform-json v0.17.1/go.mod h1:Huy6zt6euxaY9knPAFKjUITn8QxUFIe9VuSzb4zn/0o= +github.com/hashicorp/terraform-plugin-docs v0.16.0 h1:UmxFr3AScl6Wged84jndJIfFccGyBZn52KtMNsS12dI= +github.com/hashicorp/terraform-plugin-docs v0.16.0/go.mod h1:M3ZrlKBJAbPMtNOPwHicGi1c+hZUh7/g0ifT/z7TVfA= +github.com/hashicorp/terraform-plugin-go v0.19.0 h1:BuZx/6Cp+lkmiG0cOBk6Zps0Cb2tmqQpDM3iAtnhDQU= +github.com/hashicorp/terraform-plugin-go v0.19.0/go.mod h1:EhRSkEPNoylLQntYsk5KrDHTZJh9HQoumZXbOGOXmec= +github.com/hashicorp/terraform-plugin-log v0.9.0 h1:i7hOA+vdAItN1/7UrfBqBwvYPQ9TFvymaRGZED3FCV0= +github.com/hashicorp/terraform-plugin-log v0.9.0/go.mod h1:rKL8egZQ/eXSyDqzLUuwUYLVdlYeamldAHSxjUFADow= +github.com/hashicorp/terraform-plugin-sdk/v2 v2.29.0 h1:wcOKYwPI9IorAJEBLzgclh3xVolO7ZorYd6U1vnok14= +github.com/hashicorp/terraform-plugin-sdk/v2 v2.29.0/go.mod h1:qH/34G25Ugdj5FcM95cSoXzUgIbgfhVLXCcEcYaMwq8= +github.com/hashicorp/terraform-registry-address v0.2.2 h1:lPQBg403El8PPicg/qONZJDC6YlgCVbWDtNmmZKtBno= +github.com/hashicorp/terraform-registry-address v0.2.2/go.mod h1:LtwNbCihUoUZ3RYriyS2wF/lGPB6gF9ICLRtuDk7hSo= +github.com/hashicorp/terraform-svchost v0.1.1 h1:EZZimZ1GxdqFRinZ1tpJwVxxt49xc/S52uzrw4x0jKQ= +github.com/hashicorp/terraform-svchost v0.1.1/go.mod h1:mNsjQfZyf/Jhz35v6/0LWcv26+X7JPS+buii2c9/ctc= +github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE= +github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= +github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU= +github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= +github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= -github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jhump/protoreflect v1.6.0 h1:h5jfMVslIg6l29nsMs0D8Wj17RDVdNYti0vDN/PZZoE= -github.com/jhump/protoreflect v1.6.0/go.mod h1:eaTn3RZAmMBcV0fifFvlm6VHNz3wSkYyXYWUh7ymB74= -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/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o= -github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd h1:Coekwdh0v2wtGp9Gmz1Ze3eVRAWJMLokvN3QjdzCHLY= -github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= -github.com/keybase/go-crypto v0.0.0-20161004153544-93f5b35093ba/go.mod h1:ghbZscTyKdM07+Fw3KSi0hcJm+AlEUWj8QLlPtijN/M= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c= +github.com/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo= +github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= +github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= 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/labd/contentful-go v0.5.0 h1:nm7dHLDkNPZ6ZkxCoIy4Xo7/UcYsmJdOxS+SK8RIXhw= -github.com/labd/contentful-go v0.5.0/go.mod h1:nU9FmlPmgIOwTWg2czqlpRMhPQplTaPuPjuz0oIcftM= +github.com/labd/contentful-go v0.5.3 h1:dIT2OURBgV9Zf1zOAmXL4w+V9vDMNEpwBIPVTfXRzmE= +github.com/labd/contentful-go v0.5.3/go.mod h1:fJnX/J/wrmFzSdPIrOs7ZfCaHsHz0LPWGA9RGpiRHB0= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= -github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -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/mitchellh/cli v1.1.1/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= -github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mitchellh/cli v1.1.5 h1:OxRIeJXpAMztws/XHlN2vu6imG5Dpq+j61AzAX5fLng= +github.com/mitchellh/cli v1.1.5/go.mod h1:v8+iFts2sPIKUV1ltktPXMCC8fumSKFItNcD2cLtRR4= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= -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-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= -github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= -github.com/mitchellh/go-testing-interface v1.0.4 h1:ZU1VNC02qyufSZsjjs7+khruk2fKvbQ3TwRV/IBCeFA= -github.com/mitchellh/go-testing-interface v1.0.4/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= -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/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= -github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= +github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= +github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= +github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= +github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= +github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= 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/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/nsf/jsondiff v0.0.0-20200515183724-f29ed568f4ce h1:RPclfga2SEJmgMmz2k+Mg7cowZ8yv4Trqw9UsJby758= -github.com/nsf/jsondiff v0.0.0-20200515183724-f29ed568f4ce/go.mod h1:uFMI8w+ref4v2r9jz+c9i1IfIttS/OkmLfrk1jne5hs= -github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= -github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= -github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= +github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA= +github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= +github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= +github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI= 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/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= -github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/posener/complete v1.2.3 h1:NP0eAhjcjImqslEwo/1hq7gpajME0fTLTezBKDqfXqo= +github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= +github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww= +github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY= +github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= +github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= +github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/skeema/knownhosts v1.2.0 h1:h9r9cf0+u7wSE+M183ZtMGgOJKiL96brpaz5ekfJCpM= +github.com/skeema/knownhosts v1.2.0/go.mod h1:g4fPeYpque7P0xefxtGzV81ihjC8sX2IqpAoNkjxbMo= +github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA= +github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.1.4/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/ulikunitz/xz v0.5.5/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8= -github.com/ulikunitz/xz v0.5.8 h1:ERv8V6GKqVi23rgu5cj9pVfVzJbOqAY2Ntl88O6c2nQ= -github.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= +github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI= github.com/vmihailenco/msgpack v4.0.4+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/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8= -github.com/zclconf/go-cty v1.2.1 h1:vGMsygfmeCl4Xb6OA5U5XVAaQZ69FvoG7X2jUtQujb8= -github.com/zclconf/go-cty v1.2.1/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8= -github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.4 h1:LYy1Hy3MJdrCdMwwzxA/dRok4ejH+RwNGbuoD9fCjto= -go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU= +github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= +github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= +github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= +github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= +github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/zclconf/go-cty v1.14.0 h1:/Xrd39K7DXbHzlisFP9c4pHao4yyf+/Ug9LEz+Y/yhc= +github.com/zclconf/go-cty v1.14.0/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= 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= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/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-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= -golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/net v0.0.0-20180530234432-1e491301e022/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/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-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= +golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= +golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= +golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck= +golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= +golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= +golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/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-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU= -golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8= +golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 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= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200523222454-059865788121 h1:rITEj+UZHYC927n8GT97eC3zrpzXdb/voyeOuVKS46o= -golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.12.0 h1:/ZfYdc3zq+q02Rv9vGqTeSItdzZTSNDmfTi0mBAuidU= +golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200507205054-480da3ebd79c/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200713011307-fd294ab11aed h1:+qzWo37K31KxduIYaBeMqJ8MUOyTayOQKpH9aDPLMSY= -golang.org/x/tools v0.0.0-20200713011307-fd294ab11aed/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= +golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= -google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.29.0 h1:BaiDisFir8O4IJxvAabCGGkQ6yCJegNQqSVoYUNAnbk= -google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc= -google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/genproto v0.0.0-20170818010345-ee236bd376b0/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= -google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200711021454-869866162049 h1:YFTFpQhgvrLrmxtiIncJxFXeCyq84ixuKWVCaCAi9Oc= -google.golang.org/genproto v0.0.0-20200711021454-869866162049/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= -google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.32.0 h1:zWTV+LMdc3kaiJMSTOFz2UgSBgx8RNQoTGiZu3fR9S0= -google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= -google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= +google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230913181813-007df8e322eb h1:Isk1sSH7bovx8Rti2wZK0UZF6oraBDK74uoyLEEVFN0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230913181813-007df8e322eb/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= +google.golang.org/grpc v1.58.1 h1:OL+Vz23DTtrrldqHK49FUOPHyY75rvFqJfXC84NYW58= +google.golang.org/grpc v1.58.1/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/cheggaaa/pb.v1 v1.0.27/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= moul.io/http2curl v1.0.1-0.20190925090545-5cd742060b0e h1:C7q+e9M5nggAvWfVg9Nl66kebKeuJlP3FD58V4RR5wo= moul.io/http2curl v1.0.1-0.20190925090545-5cd742060b0e/go.mod h1:nejbQVfXh96n9dSF6cH3Jsk/QI1Z2oEL7sSI2ifXFNA= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= -rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/main.go b/main.go index d2ebe8b..c9e17ff 100644 --- a/main.go +++ b/main.go @@ -6,6 +6,17 @@ import ( "github.com/labd/terraform-provider-contentful/contentful" ) +// Run "go generate" to format example terraform files and generate the docs for the registry/website + +// If you do not have terraform installed, you can remove the formatting command, but its suggested to +// ensure the documentation is formatted properly. +//go:generate terraform fmt -recursive ./examples/ + +// Run the docs generation tool, check its repository for more information on how it works and how docs +// can be customized. +// +//go:generate go run github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs + func main() { plugin.Serve(&plugin.ServeOpts{ ProviderFunc: func() *schema.Provider { diff --git a/tools.go b/tools.go new file mode 100644 index 0000000..cc7a70a --- /dev/null +++ b/tools.go @@ -0,0 +1,10 @@ +//go:build tools +// +build tools + +package main + +import ( + // document generation + + _ "github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs" +) From 2893bfc4c130188dee51347d85804f4e95a62b1a Mon Sep 17 00:00:00 2001 From: Thomas De Meyer Date: Fri, 15 Sep 2023 14:59:07 +0200 Subject: [PATCH 143/192] Added changie file --- .changes/unreleased/Added-20230915-145854.yaml | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changes/unreleased/Added-20230915-145854.yaml diff --git a/.changes/unreleased/Added-20230915-145854.yaml b/.changes/unreleased/Added-20230915-145854.yaml new file mode 100644 index 0000000..8b52a99 --- /dev/null +++ b/.changes/unreleased/Added-20230915-145854.yaml @@ -0,0 +1,3 @@ +kind: Added +body: Updated to go 1.21, updated documentation and metadata files +time: 2023-09-15T14:58:54.291631882+02:00 From 86cea3d64ad1ba9ea0e2401fc3c0afbcece825d8 Mon Sep 17 00:00:00 2001 From: demeyerthom Date: Fri, 15 Sep 2023 13:03:11 +0000 Subject: [PATCH 144/192] Release v0.4.0 --- .changes/unreleased/Added-20230915-145854.yaml | 3 --- .changes/v0.4.0.md | 3 +++ CHANGELOG.md | 4 ++++ 3 files changed, 7 insertions(+), 3 deletions(-) delete mode 100644 .changes/unreleased/Added-20230915-145854.yaml create mode 100644 .changes/v0.4.0.md diff --git a/.changes/unreleased/Added-20230915-145854.yaml b/.changes/unreleased/Added-20230915-145854.yaml deleted file mode 100644 index 8b52a99..0000000 --- a/.changes/unreleased/Added-20230915-145854.yaml +++ /dev/null @@ -1,3 +0,0 @@ -kind: Added -body: Updated to go 1.21, updated documentation and metadata files -time: 2023-09-15T14:58:54.291631882+02:00 diff --git a/.changes/v0.4.0.md b/.changes/v0.4.0.md new file mode 100644 index 0000000..51f75be --- /dev/null +++ b/.changes/v0.4.0.md @@ -0,0 +1,3 @@ +## v0.4.0 - 2023-09-15 +### Added +* Updated to go 1.21, updated documentation and metadata files diff --git a/CHANGELOG.md b/CHANGELOG.md index 7eb6901..4a76c2a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), and is generated by [Changie](https://github.com/miniscruff/changie). +## v0.4.0 - 2023-09-15 +### Added +* Updated to go 1.21, updated documentation and metadata files + 0.3.1 (2021-04-30) ================== # Fixes From 2bbfbec32b7c40d2304bf850cf17337a80b15b5d Mon Sep 17 00:00:00 2001 From: "alexander.miehe" Date: Wed, 25 Oct 2023 13:15:17 +0200 Subject: [PATCH 145/192] PLT-684 - Add support for locales in env * adjust the code to be able to handle locales in environments * update locale code --- contentful/resource_contentful_locale.go | 194 ++++++++++++++---- contentful/resource_contentful_locale_test.go | 6 +- go.mod | 2 + go.sum | 4 +- 4 files changed, 160 insertions(+), 46 deletions(-) diff --git a/contentful/resource_contentful_locale.go b/contentful/resource_contentful_locale.go index f31e9c7..86f312e 100644 --- a/contentful/resource_contentful_locale.go +++ b/contentful/resource_contentful_locale.go @@ -1,16 +1,53 @@ package contentful import ( + "context" + "errors" + "fmt" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - contentful "github.com/labd/contentful-go" + "github.com/labd/contentful-go" + "strings" ) +func resourceContentfulLocaleParseImportId(id string) (string, string, string, error) { + parts := strings.SplitN(id, ":", 3) + + if len(parts) != 3 || parts[0] == "" || parts[1] == "" || parts[2] == "" { + return "", "", "", fmt.Errorf("unexpected format of ID (%s), expected localeId:env:spaceId", id) + } + + return parts[0], parts[1], parts[2], nil +} + func resourceContentfulLocale() *schema.Resource { return &schema.Resource{ - Create: resourceCreateLocale, - Read: resourceReadLocale, - Update: resourceUpdateLocale, - Delete: resourceDeleteLocale, + CreateContext: resourceCreateLocale, + ReadContext: resourceReadLocale, + UpdateContext: resourceUpdateLocale, + DeleteContext: resourceDeleteLocale, + Importer: &schema.ResourceImporter{ + StateContext: func(ctx context.Context, d *schema.ResourceData, meta any) ([]*schema.ResourceData, error) { + id, environment, spaceId, err := resourceContentfulLocaleParseImportId(d.Id()) + + if err != nil { + return nil, err + } + + err = d.Set("environment", environment) + if err != nil { + return nil, err + } + + err = d.Set("space_id", spaceId) + if err != nil { + return nil, err + } + d.SetId(id) + + return []*schema.ResourceData{d}, nil + }, + }, Schema: map[string]*schema.Schema{ "version": { @@ -32,7 +69,6 @@ func resourceContentfulLocale() *schema.Resource { "fallback_code": { Type: schema.TypeString, Optional: true, - Default: "en-US", }, "optional": { Type: schema.TypeBool, @@ -49,31 +85,55 @@ func resourceContentfulLocale() *schema.Resource { Optional: true, Default: false, }, + "environment": { + Type: schema.TypeString, + Optional: true, + }, }, } } -func resourceCreateLocale(d *schema.ResourceData, m interface{}) (err error) { +func resourceCreateLocale(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) + var err error locale := &contentful.Locale{ Name: d.Get("name").(string), Code: d.Get("code").(string), - FallbackCode: d.Get("fallback_code").(string), + FallbackCode: nil, Optional: d.Get("optional").(bool), CDA: d.Get("cda").(bool), CMA: d.Get("cma").(bool), } - err = client.Locales.Upsert(spaceID, locale) - if err != nil { - return err + if fallbackCode, ok := d.GetOk("fallback_code"); ok { + + fallbackCodeStr := fallbackCode.(string) + + locale.FallbackCode = &fallbackCodeStr + } + + if environment, ok := d.GetOk("environment"); ok { + + env, envErr := client.Environments.Get(spaceID, environment.(string)) + + if envErr != nil { + return diag.FromErr(envErr) + } + + err = client.Locales.UpsertWithEnv(env, locale) + } else { + err = client.Locales.Upsert(spaceID, locale) } - err = setLocaleProperties(d, locale) if err != nil { - return err + return diag.FromErr(err) + } + + diagErr := setLocaleProperties(d, locale) + if diagErr != nil { + return diagErr } d.SetId(locale.Sys.ID) @@ -81,106 +141,158 @@ func resourceCreateLocale(d *schema.ResourceData, m interface{}) (err error) { return nil } -func resourceReadLocale(d *schema.ResourceData, m interface{}) error { +func resourceReadLocale(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { client := m.(*contentful.Client) - spaceID := d.Get("space_id").(string) localeID := d.Id() - locale, err := client.Locales.Get(spaceID, localeID) - if _, ok := err.(*contentful.NotFoundError); ok { + locale, err := readLocale(d, client, localeID) + + var notFoundError *contentful.NotFoundError + if errors.As(err, ¬FoundError) { d.SetId("") return nil } if err != nil { - return err + return diag.FromErr(err) } return setLocaleProperties(d, locale) } -func resourceUpdateLocale(d *schema.ResourceData, m interface{}) (err error) { +func resourceUpdateLocale(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) localeID := d.Id() - locale, err := client.Locales.Get(spaceID, localeID) + locale, err := readLocale(d, client, localeID) + if err != nil { - return err + return diag.FromErr(err) } locale.Name = d.Get("name").(string) locale.Code = d.Get("code").(string) - locale.FallbackCode = d.Get("fallback_code").(string) + + locale.FallbackCode = nil + + if fallbackCode, ok := d.GetOk("fallback_code"); ok { + + fallbackCodeStr := fallbackCode.(string) + + locale.FallbackCode = &fallbackCodeStr + } + locale.Optional = d.Get("optional").(bool) locale.CDA = d.Get("cda").(bool) locale.CMA = d.Get("cma").(bool) - err = client.Locales.Upsert(spaceID, locale) - if err != nil { - return err + if environment, ok := d.GetOk("environment"); ok { + env, envErr := client.Environments.Get(spaceID, environment.(string)) + + if envErr != nil { + return diag.FromErr(envErr) + } + + err = client.Locales.UpsertWithEnv(env, locale) + + } else { + err = client.Locales.Upsert(spaceID, locale) } - err = setLocaleProperties(d, locale) if err != nil { - return err + return diag.FromErr(err) } - return nil + return setLocaleProperties(d, locale) } -func resourceDeleteLocale(d *schema.ResourceData, m interface{}) (err error) { +func resourceDeleteLocale(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) localeID := d.Id() - locale, err := client.Locales.Get(spaceID, localeID) + locale, err := readLocale(d, client, localeID) + if err != nil { - return err + return diag.FromErr(err) } - err = client.Locales.Delete(spaceID, locale) - if _, ok := err.(*contentful.NotFoundError); ok { + if environment, ok := d.GetOk("environment"); ok { + env, envErr := client.Environments.Get(spaceID, environment.(string)) + + if envErr != nil { + return diag.FromErr(envErr) + } + + err = client.Locales.DeleteWithEnv(env, locale) + + } else { + err = client.Locales.Delete(spaceID, locale) + } + + var notFoundError *contentful.NotFoundError + if errors.As(err, ¬FoundError) { return nil } if err != nil { - return err + return diag.FromErr(err) } return nil } -func setLocaleProperties(d *schema.ResourceData, locale *contentful.Locale) error { +func setLocaleProperties(d *schema.ResourceData, locale *contentful.Locale) diag.Diagnostics { err := d.Set("name", locale.Name) if err != nil { - return err + return diag.FromErr(err) } err = d.Set("code", locale.Code) if err != nil { - return err + return diag.FromErr(err) } err = d.Set("fallback_code", locale.FallbackCode) if err != nil { - return err + return diag.FromErr(err) } err = d.Set("optional", locale.Optional) if err != nil { - return err + return diag.FromErr(err) } err = d.Set("cda", locale.CDA) if err != nil { - return err + return diag.FromErr(err) } err = d.Set("cma", locale.CMA) if err != nil { - return err + return diag.FromErr(err) + } + + err = d.Set("version", locale.Sys.Version) + if err != nil { + return diag.FromErr(err) } return nil } + +func readLocale(d *schema.ResourceData, client *contentful.Client, localeID string) (*contentful.Locale, error) { + spaceID := d.Get("space_id").(string) + if environment, ok := d.GetOk("environment"); ok { + env, envErr := client.Environments.Get(spaceID, environment.(string)) + + if envErr != nil { + return nil, envErr + } + + return client.Locales.GetWithEnv(env, localeID) + } else { + return client.Locales.Get(spaceID, localeID) + } +} diff --git a/contentful/resource_contentful_locale_test.go b/contentful/resource_contentful_locale_test.go index 041d507..e98da56 100644 --- a/contentful/resource_contentful_locale_test.go +++ b/contentful/resource_contentful_locale_test.go @@ -7,7 +7,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" - contentful "github.com/labd/contentful-go" + "github.com/labd/contentful-go" ) func TestAccContentfulLocales_Basic(t *testing.T) { @@ -95,8 +95,8 @@ func testAccCheckContentfulLocaleAttributes(locale *contentful.Locale, attrs map } fallbackCode := attrs["fallback_code"].(string) - if locale.FallbackCode != fallbackCode { - return fmt.Errorf("locale fallback code does not match: %s, %s", locale.FallbackCode, fallbackCode) + if *locale.FallbackCode != fallbackCode { + return fmt.Errorf("locale fallback code does not match: %s, %s", *locale.FallbackCode, fallbackCode) } isOptional := attrs["optional"].(bool) diff --git a/go.mod b/go.mod index 105f009..354ea07 100644 --- a/go.mod +++ b/go.mod @@ -75,3 +75,5 @@ require ( google.golang.org/protobuf v1.31.0 // indirect moul.io/http2curl v1.0.1-0.20190925090545-5cd742060b0e // indirect ) + +replace github.com/labd/contentful-go v0.5.3 => github.com/flaconi/contentful-go v0.5.3-0.20231024101932-f0a47fb0102a diff --git a/go.sum b/go.sum index b675fca..15b7e99 100644 --- a/go.sum +++ b/go.sum @@ -39,6 +39,8 @@ github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5Kwzbycv github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= +github.com/flaconi/contentful-go v0.5.3-0.20231024101932-f0a47fb0102a h1:gIZXCIHX1mZPue4zR9T8e689OlWW8smL55MdZWWiLXY= +github.com/flaconi/contentful-go v0.5.3-0.20231024101932-f0a47fb0102a/go.mod h1:ciVUTFqeUtSSNjuEQnYLqbXvAlPu/aiPU4CsUc6Ug80= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= @@ -133,8 +135,6 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= 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/labd/contentful-go v0.5.3 h1:dIT2OURBgV9Zf1zOAmXL4w+V9vDMNEpwBIPVTfXRzmE= -github.com/labd/contentful-go v0.5.3/go.mod h1:fJnX/J/wrmFzSdPIrOs7ZfCaHsHz0LPWGA9RGpiRHB0= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= From ddd3d32b34a31a1ce3e42e42213248f1daffa184 Mon Sep 17 00:00:00 2001 From: "alexander.miehe" Date: Wed, 25 Oct 2023 14:54:36 +0200 Subject: [PATCH 146/192] PLT-684 - Prepare release --- .changes/unreleased/Added-20231025-144959.yaml | 3 +++ .github/workflows/release.yaml | 8 ++++---- .github/workflows/tests.yaml | 8 ++++---- 3 files changed, 11 insertions(+), 8 deletions(-) create mode 100644 .changes/unreleased/Added-20231025-144959.yaml diff --git a/.changes/unreleased/Added-20231025-144959.yaml b/.changes/unreleased/Added-20231025-144959.yaml new file mode 100644 index 0000000..f47b6d5 --- /dev/null +++ b/.changes/unreleased/Added-20231025-144959.yaml @@ -0,0 +1,3 @@ +kind: Added +body: Added Support for locales in environments,Update github actions +time: 2023-10-25T14:49:59.269212+02:00 diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 612af53..57570a2 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -7,7 +7,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 0 @@ -18,10 +18,10 @@ jobs: - name: Import GPG key id: import_gpg - uses: paultyng/ghaction-import-gpg@v2.1.0 + uses: crazy-max/ghaction-import-gpg@v6.0.0 env: - GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} - PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} + gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} + passphrase: ${{ secrets.GPG_PASSPHRASE }} - name: Run GoReleaser uses: goreleaser/goreleaser-action@v2 diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index abbc635..87002cf 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -8,10 +8,10 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Set up Go 1.21 - uses: actions/setup-go@v2 + uses: actions/setup-go@v4 with: go-version: "1.21" @@ -38,12 +38,12 @@ jobs: pull-requests: write actions: write steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Prepare release - uses: labd/changie-release-action@v0.2.0 + uses: labd/changie-release-action@v0.3.0 with: github-token: ${{ secrets.GITHUB_TOKEN }} release-workflow: 'release.yaml' From 441435a71fab259a74119b09f66e93b29171774d Mon Sep 17 00:00:00 2001 From: Engerim Date: Wed, 25 Oct 2023 13:31:30 +0000 Subject: [PATCH 147/192] Release v0.5.0 --- .changes/unreleased/Added-20231025-144959.yaml | 3 --- .changes/v0.5.0.md | 3 +++ CHANGELOG.md | 4 ++++ 3 files changed, 7 insertions(+), 3 deletions(-) delete mode 100644 .changes/unreleased/Added-20231025-144959.yaml create mode 100644 .changes/v0.5.0.md diff --git a/.changes/unreleased/Added-20231025-144959.yaml b/.changes/unreleased/Added-20231025-144959.yaml deleted file mode 100644 index f47b6d5..0000000 --- a/.changes/unreleased/Added-20231025-144959.yaml +++ /dev/null @@ -1,3 +0,0 @@ -kind: Added -body: Added Support for locales in environments,Update github actions -time: 2023-10-25T14:49:59.269212+02:00 diff --git a/.changes/v0.5.0.md b/.changes/v0.5.0.md new file mode 100644 index 0000000..7e39f4f --- /dev/null +++ b/.changes/v0.5.0.md @@ -0,0 +1,3 @@ +## v0.5.0 - 2023-10-25 +### Added +* Added Support for locales in environments,Update github actions diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a76c2a..c496d90 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), and is generated by [Changie](https://github.com/miniscruff/changie). +## v0.5.0 - 2023-10-25 +### Added +* Added Support for locales in environments,Update github actions + ## v0.4.0 - 2023-09-15 ### Added * Updated to go 1.21, updated documentation and metadata files From eb9e881c56e7272c4d3e878142015a7cf4076c51 Mon Sep 17 00:00:00 2001 From: "alexander.miehe" Date: Wed, 25 Oct 2023 15:36:43 +0200 Subject: [PATCH 148/192] PLT-684 - Fix passphrase --- .changes/unreleased/Fixed-20231025-153627.yaml | 3 +++ .github/workflows/release.yaml | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 .changes/unreleased/Fixed-20231025-153627.yaml diff --git a/.changes/unreleased/Fixed-20231025-153627.yaml b/.changes/unreleased/Fixed-20231025-153627.yaml new file mode 100644 index 0000000..86fb735 --- /dev/null +++ b/.changes/unreleased/Fixed-20231025-153627.yaml @@ -0,0 +1,3 @@ +kind: Fixed +body: set correct secret for gpg +time: 2023-10-25T15:36:27.514685+02:00 diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 57570a2..0411b64 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -21,7 +21,7 @@ jobs: uses: crazy-max/ghaction-import-gpg@v6.0.0 env: gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} - passphrase: ${{ secrets.GPG_PASSPHRASE }} + passphrase: ${{ secrets.PASSPHRASE }} - name: Run GoReleaser uses: goreleaser/goreleaser-action@v2 From 91d783e0f56f5d8c674d7e3245632bad2c61e1c1 Mon Sep 17 00:00:00 2001 From: Engerim Date: Wed, 25 Oct 2023 13:40:29 +0000 Subject: [PATCH 149/192] Release v0.5.1 --- .changes/unreleased/Fixed-20231025-153627.yaml | 3 --- .changes/v0.5.1.md | 3 +++ CHANGELOG.md | 4 ++++ 3 files changed, 7 insertions(+), 3 deletions(-) delete mode 100644 .changes/unreleased/Fixed-20231025-153627.yaml create mode 100644 .changes/v0.5.1.md diff --git a/.changes/unreleased/Fixed-20231025-153627.yaml b/.changes/unreleased/Fixed-20231025-153627.yaml deleted file mode 100644 index 86fb735..0000000 --- a/.changes/unreleased/Fixed-20231025-153627.yaml +++ /dev/null @@ -1,3 +0,0 @@ -kind: Fixed -body: set correct secret for gpg -time: 2023-10-25T15:36:27.514685+02:00 diff --git a/.changes/v0.5.1.md b/.changes/v0.5.1.md new file mode 100644 index 0000000..b53c804 --- /dev/null +++ b/.changes/v0.5.1.md @@ -0,0 +1,3 @@ +## v0.5.1 - 2023-10-25 +### Fixed +* set correct secret for gpg diff --git a/CHANGELOG.md b/CHANGELOG.md index c496d90..451c824 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), and is generated by [Changie](https://github.com/miniscruff/changie). +## v0.5.1 - 2023-10-25 +### Fixed +* set correct secret for gpg + ## v0.5.0 - 2023-10-25 ### Added * Added Support for locales in environments,Update github actions From 67aa50b596351a89f122608c8103d00c7021bf5a Mon Sep 17 00:00:00 2001 From: "alexander.miehe" Date: Wed, 25 Oct 2023 15:45:38 +0200 Subject: [PATCH 150/192] PLT-684 - Fix action --- .changes/unreleased/Fixed-20231025-154502.yaml | 3 +++ .github/workflows/release.yaml | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 .changes/unreleased/Fixed-20231025-154502.yaml diff --git a/.changes/unreleased/Fixed-20231025-154502.yaml b/.changes/unreleased/Fixed-20231025-154502.yaml new file mode 100644 index 0000000..723d86a --- /dev/null +++ b/.changes/unreleased/Fixed-20231025-154502.yaml @@ -0,0 +1,3 @@ +kind: Fixed +body: use action correct +time: 2023-10-25T15:45:02.701846+02:00 diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 0411b64..913264e 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -19,7 +19,7 @@ jobs: - name: Import GPG key id: import_gpg uses: crazy-max/ghaction-import-gpg@v6.0.0 - env: + with: gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} passphrase: ${{ secrets.PASSPHRASE }} From f5fedbb306860b542ac6af8e9bd108e631e3b03a Mon Sep 17 00:00:00 2001 From: Engerim Date: Wed, 25 Oct 2023 13:52:15 +0000 Subject: [PATCH 151/192] Release v0.5.2 --- .changes/unreleased/Fixed-20231025-154502.yaml | 3 --- .changes/v0.5.2.md | 3 +++ CHANGELOG.md | 4 ++++ 3 files changed, 7 insertions(+), 3 deletions(-) delete mode 100644 .changes/unreleased/Fixed-20231025-154502.yaml create mode 100644 .changes/v0.5.2.md diff --git a/.changes/unreleased/Fixed-20231025-154502.yaml b/.changes/unreleased/Fixed-20231025-154502.yaml deleted file mode 100644 index 723d86a..0000000 --- a/.changes/unreleased/Fixed-20231025-154502.yaml +++ /dev/null @@ -1,3 +0,0 @@ -kind: Fixed -body: use action correct -time: 2023-10-25T15:45:02.701846+02:00 diff --git a/.changes/v0.5.2.md b/.changes/v0.5.2.md new file mode 100644 index 0000000..0bbf1c7 --- /dev/null +++ b/.changes/v0.5.2.md @@ -0,0 +1,3 @@ +## v0.5.2 - 2023-10-25 +### Fixed +* use action correct diff --git a/CHANGELOG.md b/CHANGELOG.md index 451c824..3dd2bf2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), and is generated by [Changie](https://github.com/miniscruff/changie). +## v0.5.2 - 2023-10-25 +### Fixed +* use action correct + ## v0.5.1 - 2023-10-25 ### Fixed * set correct secret for gpg From b58e7078a946d706477f0628bd41db0399cfbf24 Mon Sep 17 00:00:00 2001 From: "alexander.miehe" Date: Mon, 6 Nov 2023 09:06:47 +0100 Subject: [PATCH 152/192] PLT-684 - Extend support in content types * allow creation of content types per env * add support for content type editor interfaces * support more validations * move for content_types to terraform plugin framework * add base test --- .../unreleased/Changed-20231106-090931.yaml | 3 + contentful/provider.go | 62 +- contentful/provider_test.go | 4 +- contentful/resource_contentful_contenttype.go | 357 -------- .../resource_contentful_contenttype_test.go | 201 ----- contentful/resource_contentful_locale.go | 23 +- go.mod | 16 +- go.sum | 32 +- internal/acctest/acctest.go | 19 + internal/acctest/client.go | 16 + internal/custommodifier/booldefault.go | 40 + internal/custommodifier/int64default.go | 40 + .../stringallowedwhensetvalidator.go | 101 +++ internal/provider/provider.go | 110 +++ internal/resources/contenttype/model.go | 773 ++++++++++++++++++ internal/resources/contenttype/resource.go | 718 ++++++++++++++++ .../resources/contenttype/resource_test.go | 189 +++++ internal/utils/container.go | 7 + internal/utils/fields.go | 13 + internal/utils/hcl.go | 16 + main.go | 67 +- 21 files changed, 2183 insertions(+), 624 deletions(-) create mode 100644 .changes/unreleased/Changed-20231106-090931.yaml delete mode 100644 contentful/resource_contentful_contenttype.go delete mode 100644 contentful/resource_contentful_contenttype_test.go create mode 100644 internal/acctest/acctest.go create mode 100644 internal/acctest/client.go create mode 100644 internal/custommodifier/booldefault.go create mode 100644 internal/custommodifier/int64default.go create mode 100644 internal/customvalidator/stringallowedwhensetvalidator.go create mode 100644 internal/provider/provider.go create mode 100644 internal/resources/contenttype/model.go create mode 100644 internal/resources/contenttype/resource.go create mode 100644 internal/resources/contenttype/resource_test.go create mode 100644 internal/utils/container.go create mode 100644 internal/utils/fields.go create mode 100644 internal/utils/hcl.go diff --git a/.changes/unreleased/Changed-20231106-090931.yaml b/.changes/unreleased/Changed-20231106-090931.yaml new file mode 100644 index 0000000..49cd211 --- /dev/null +++ b/.changes/unreleased/Changed-20231106-090931.yaml @@ -0,0 +1,3 @@ +kind: Changed +body: Extended ContentType to support enviroments, more validations, locales in environments +time: 2023-11-06T09:09:31.737754+01:00 diff --git a/contentful/provider.go b/contentful/provider.go index 0077450..d293937 100644 --- a/contentful/provider.go +++ b/contentful/provider.go @@ -1,43 +1,51 @@ package contentful import ( + "context" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - contentful "github.com/labd/contentful-go" + "github.com/labd/contentful-go" ) // Provider returns the Terraform Provider as a scheme and makes resources reachable -func Provider() *schema.Provider { - return &schema.Provider{ - Schema: map[string]*schema.Schema{ - "cma_token": { - Type: schema.TypeString, - Required: true, - DefaultFunc: schema.EnvDefaultFunc("CONTENTFUL_MANAGEMENT_TOKEN", nil), - Description: "The Contentful Management API token", +func Provider() func() *schema.Provider { + return func() *schema.Provider { + p := &schema.Provider{ + Schema: map[string]*schema.Schema{ + "cma_token": { + Type: schema.TypeString, + Optional: true, + Sensitive: true, + DefaultFunc: schema.EnvDefaultFunc("CONTENTFUL_MANAGEMENT_TOKEN", nil), + Description: "The Contentful Management API token", + }, + "organization_id": { + Type: schema.TypeString, + Optional: true, + Sensitive: true, + DefaultFunc: schema.EnvDefaultFunc("CONTENTFUL_ORGANIZATION_ID", nil), + Description: "The organization ID", + }, }, - "organization_id": { - Type: schema.TypeString, - Required: true, - DefaultFunc: schema.EnvDefaultFunc("CONTENTFUL_ORGANIZATION_ID", nil), - Description: "The organization ID", + ResourcesMap: map[string]*schema.Resource{ + "contentful_space": resourceContentfulSpace(), + "contentful_apikey": resourceContentfulAPIKey(), + "contentful_webhook": resourceContentfulWebhook(), + "contentful_locale": resourceContentfulLocale(), + "contentful_environment": resourceContentfulEnvironment(), + "contentful_entry": resourceContentfulEntry(), + "contentful_asset": resourceContentfulAsset(), }, - }, - ResourcesMap: map[string]*schema.Resource{ - "contentful_space": resourceContentfulSpace(), - "contentful_contenttype": resourceContentfulContentType(), - "contentful_apikey": resourceContentfulAPIKey(), - "contentful_webhook": resourceContentfulWebhook(), - "contentful_locale": resourceContentfulLocale(), - "contentful_environment": resourceContentfulEnvironment(), - "contentful_entry": resourceContentfulEntry(), - "contentful_asset": resourceContentfulAsset(), - }, - ConfigureFunc: providerConfigure, + ConfigureContextFunc: providerConfigure, + } + + return p } + } // providerConfigure sets the configuration for the Terraform Provider -func providerConfigure(d *schema.ResourceData) (interface{}, error) { +func providerConfigure(_ context.Context, d *schema.ResourceData) (interface{}, diag.Diagnostics) { cma := contentful.NewCMA(d.Get("cma_token").(string)) cma.SetOrganization(d.Get("organization_id").(string)) diff --git a/contentful/provider_test.go b/contentful/provider_test.go index c9bd83e..b4eff67 100644 --- a/contentful/provider_test.go +++ b/contentful/provider_test.go @@ -10,14 +10,14 @@ var testAccProviders map[string]*schema.Provider var testAccProvider *schema.Provider func init() { - testAccProvider = Provider() + testAccProvider = Provider()() testAccProviders = map[string]*schema.Provider{ "contentful": testAccProvider, } } func TestProvider(t *testing.T) { - if err := Provider().InternalValidate(); err != nil { + if err := Provider()().InternalValidate(); err != nil { t.Fatalf("err: %s", err) } } diff --git a/contentful/resource_contentful_contenttype.go b/contentful/resource_contentful_contenttype.go deleted file mode 100644 index a687e7e..0000000 --- a/contentful/resource_contentful_contenttype.go +++ /dev/null @@ -1,357 +0,0 @@ -package contentful - -import ( - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - contentful "github.com/labd/contentful-go" -) - -func resourceContentfulContentType() *schema.Resource { - return &schema.Resource{ - Create: resourceContentTypeCreate, - Read: resourceContentTypeRead, - Update: resourceContentTypeUpdate, - Delete: resourceContentTypeDelete, - - Schema: map[string]*schema.Schema{ - "space_id": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - }, - "version": { - Type: schema.TypeInt, - Computed: true, - }, - "name": { - Type: schema.TypeString, - Required: true, - }, - "description": { - Type: schema.TypeString, - Optional: true, - }, - "display_field": { - Type: schema.TypeString, - Required: true, - }, - "field": { - Type: schema.TypeList, - Required: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "id": { - Type: schema.TypeString, - Required: true, - }, - "name": { - Type: schema.TypeString, - Required: true, - }, - "type": { - Type: schema.TypeString, - Required: true, - }, - "link_type": { - Type: schema.TypeString, - Optional: true, - }, - "items": { - Type: schema.TypeList, - Optional: true, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "type": { - Type: schema.TypeString, - Required: true, - }, - "link_type": { - Type: schema.TypeString, - Required: true, - }, - "validations": { - Type: schema.TypeList, - Optional: true, - Elem: &schema.Schema{Type: schema.TypeString}, - }, - }, - }, - }, - "required": { - Type: schema.TypeBool, - Optional: true, - Default: false, - }, - "localized": { - Type: schema.TypeBool, - Optional: true, - Default: false, - }, - "disabled": { - Type: schema.TypeBool, - Optional: true, - Default: false, - }, - "omitted": { - Type: schema.TypeBool, - Optional: true, - Default: false, - }, - "validations": { - Type: schema.TypeList, - Optional: true, - Elem: &schema.Schema{Type: schema.TypeString}, - }, - }, - }, - }, - }, - } -} - -func resourceContentTypeCreate(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Client) - spaceID := d.Get("space_id").(string) - - ct := &contentful.ContentType{ - Name: d.Get("name").(string), - DisplayField: d.Get("display_field").(string), - Fields: []*contentful.Field{}, - } - - if description, ok := d.GetOk("description"); ok { - ct.Description = description.(string) - } - - rawField := d.Get("field").([]interface{}) - for i := 0; i < len(rawField); i++ { - field := rawField[i].(map[string]interface{}) - - contentfulField := &contentful.Field{ - ID: field["id"].(string), - Name: field["name"].(string), - Type: field["type"].(string), - Localized: field["localized"].(bool), - Required: field["required"].(bool), - Disabled: field["disabled"].(bool), - Omitted: field["omitted"].(bool), - } - - if linkType, ok := field["link_type"].(string); ok { - contentfulField.LinkType = linkType - } - - if validations, ok := field["validations"].([]interface{}); ok { - parsedValidations, err := contentful.ParseValidations(validations) - if err != nil { - return err - } - - contentfulField.Validations = parsedValidations - } - - if items := processItems(field["items"].([]interface{})); items != nil { - contentfulField.Items = items - } - - ct.Fields = append(ct.Fields, contentfulField) - } - - if err = client.ContentTypes.Upsert(spaceID, ct); err != nil { - return err - } - - if err = client.ContentTypes.Activate(spaceID, ct); err != nil { - return err - } - - if err = setContentTypeProperties(d, ct); err != nil { - return err - } - - d.SetId(ct.Sys.ID) - - return nil -} - -func resourceContentTypeRead(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Client) - spaceID := d.Get("space_id").(string) - - _, err = client.ContentTypes.Get(spaceID, d.Id()) - - return err -} - -func resourceContentTypeUpdate(d *schema.ResourceData, m interface{}) (err error) { - var existingFields []*contentful.Field - var deletedFields []*contentful.Field - - client := m.(*contentful.Client) - spaceID := d.Get("space_id").(string) - - ct, err := client.ContentTypes.Get(spaceID, d.Id()) - if err != nil { - return err - } - - ct.Name = d.Get("name").(string) - ct.DisplayField = d.Get("display_field").(string) - - if description, ok := d.GetOk("description"); ok { - ct.Description = description.(string) - } - - if d.HasChange("field") { - old, nw := d.GetChange("field") - - existingFields, deletedFields = checkFieldChanges(old.([]interface{}), nw.([]interface{})) - - ct.Fields = existingFields - - if deletedFields != nil { - ct.Fields = append(ct.Fields, deletedFields...) - } - } - - // To remove a field from a content type 4 API calls need to be made. - // Omit the removed fields and publish the new version of the content type, - // followed by the field removal and final publish. - if err = client.ContentTypes.Upsert(spaceID, ct); err != nil { - return err - } - - if err = client.ContentTypes.Activate(spaceID, ct); err != nil { - return err - } - - if deletedFields != nil { - ct.Fields = existingFields - - if err = client.ContentTypes.Upsert(spaceID, ct); err != nil { - return err - } - - if err = client.ContentTypes.Activate(spaceID, ct); err != nil { - return err - } - } - - return setContentTypeProperties(d, ct) -} - -func resourceContentTypeDelete(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Client) - spaceID := d.Get("space_id").(string) - - ct, err := client.ContentTypes.Get(spaceID, d.Id()) - if err != nil { - return err - } - - err = client.ContentTypes.Deactivate(spaceID, ct) - if err != nil { - return err - } - - if err = client.ContentTypes.Delete(spaceID, ct); err != nil { - return err - } - - return nil -} - -func setContentTypeProperties(d *schema.ResourceData, ct *contentful.ContentType) (err error) { - - if err = d.Set("version", ct.Sys.Version); err != nil { - return err - } - - return nil -} - -func checkFieldChanges(old, new []interface{}) ([]*contentful.Field, []*contentful.Field) { - var contentfulField *contentful.Field - var existingFields []*contentful.Field - var deletedFields []*contentful.Field - var fieldRemoved bool - - for i := 0; i < len(old); i++ { - oldField := old[i].(map[string]interface{}) - - fieldRemoved = true - for j := 0; j < len(new); j++ { - if oldField["id"].(string) == new[j].(map[string]interface{})["id"].(string) { - fieldRemoved = false - break - } - } - - if fieldRemoved { - deletedFields = append(deletedFields, - &contentful.Field{ - ID: oldField["id"].(string), - Name: oldField["name"].(string), - Type: oldField["type"].(string), - LinkType: oldField["link_type"].(string), - Localized: oldField["localized"].(bool), - Required: oldField["required"].(bool), - Disabled: oldField["disabled"].(bool), - Omitted: true, - }) - } - } - - for k := 0; k < len(new); k++ { - newField := new[k].(map[string]interface{}) - - contentfulField = &contentful.Field{ - ID: newField["id"].(string), - Name: newField["name"].(string), - Type: newField["type"].(string), - Localized: newField["localized"].(bool), - Required: newField["required"].(bool), - Disabled: newField["disabled"].(bool), - Omitted: newField["omitted"].(bool), - } - - if linkType, ok := newField["link_type"].(string); ok { - contentfulField.LinkType = linkType - } - - if validations, ok := newField["validations"].([]interface{}); ok { - parsedValidations, _ := contentful.ParseValidations(validations) - - contentfulField.Validations = parsedValidations - } - - if items := processItems(newField["items"].([]interface{})); items != nil { - contentfulField.Items = items - } - - existingFields = append(existingFields, contentfulField) - } - - return existingFields, deletedFields -} - -func processItems(fieldItems []interface{}) *contentful.FieldTypeArrayItem { - var items *contentful.FieldTypeArrayItem - - for i := 0; i < len(fieldItems); i++ { - item := fieldItems[i].(map[string]interface{}) - - var validations []contentful.FieldValidation - - if fieldValidations, ok := item["validations"].([]interface{}); ok { - validations, _ = contentful.ParseValidations(fieldValidations) - } - - items = &contentful.FieldTypeArrayItem{ - Type: item["type"].(string), - Validations: validations, - LinkType: item["link_type"].(string), - } - } - return items -} diff --git a/contentful/resource_contentful_contenttype_test.go b/contentful/resource_contentful_contenttype_test.go deleted file mode 100644 index 10d4cc3..0000000 --- a/contentful/resource_contentful_contenttype_test.go +++ /dev/null @@ -1,201 +0,0 @@ -package contentful - -import ( - "fmt" - "testing" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" - contentful "github.com/labd/contentful-go" -) - -func TestAccContentfulContentType_Basic(t *testing.T) { - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckContentfulContentTypeDestroy, - Steps: []resource.TestStep{ - { - Config: testAccContentfulContentTypeConfig, - Check: resource.TestCheckResourceAttr( - "contentful_contenttype.mycontenttype", "name", "tf_test1"), - }, - { - Config: testAccContentfulContentTypeUpdateConfig, - Check: resource.TestCheckResourceAttr( - "contentful_contenttype.mycontenttype", "name", "tf_test1"), - }, - { - Config: testAccContentfulContentTypeLinkConfig, - Check: resource.TestCheckResourceAttr( - "contentful_contenttype.mylinked_contenttype", "name", "tf_linked"), - }, - }, - }) -} - -// noinspection GoUnusedFunction -func testAccCheckContentfulContentTypeExists(n string, contentType *contentful.ContentType) resource.TestCheckFunc { - return func(s *terraform.State) error { - rs, ok := s.RootModule().Resources[n] - if !ok { - return fmt.Errorf("not found %s", n) - } - - if rs.Primary.ID == "" { - return fmt.Errorf("no content type ID is set") - } - - spaceID := rs.Primary.Attributes["space_id"] - if spaceID == "" { - return fmt.Errorf("no space_id is set") - } - - client := testAccProvider.Meta().(*contentful.Client) - - ct, err := client.ContentTypes.Get(spaceID, rs.Primary.ID) - if err != nil { - return err - } - - *contentType = *ct - - return nil - } -} - -func testAccCheckContentfulContentTypeDestroy(s *terraform.State) (err error) { - for _, rs := range s.RootModule().Resources { - if rs.Type != "contentful_contenttype" { - continue - } - - spaceID := rs.Primary.Attributes["space_id"] - if spaceID == "" { - return fmt.Errorf("no space_id is set") - } - - client := testAccProvider.Meta().(*contentful.Client) - - _, err := client.ContentTypes.Get(spaceID, rs.Primary.ID) - if _, ok := err.(contentful.NotFoundError); ok { - return nil - } - - return fmt.Errorf("content type still exists with id: %s", rs.Primary.ID) - } - - return nil -} - -var testAccContentfulContentTypeConfig = ` -resource "contentful_contenttype" "mycontenttype" { - space_id = "` + spaceID + `" - name = "tf_test1" - description = "Terraform Acc Test Content Type" - display_field = "field1" - field { - disabled = false - id = "field1" - localized = false - name = "Field 1" - omitted = false - required = true - type = "Text" - } - field { - disabled = false - id = "field2" - localized = false - name = "Field 2" - omitted = false - required = true - type = "Integer" - } -} -` - -var testAccContentfulContentTypeUpdateConfig = ` -resource "contentful_contenttype" "mycontenttype" { - space_id = "` + spaceID + `" - name = "tf_test1" - description = "Terraform Acc Test Content Type description change" - display_field = "field1" - field { - disabled = false - id = "field1" - localized = false - name = "Field 1 name change" - omitted = false - required = true - type = "Text" - } - field { - disabled = false - id = "field3" - localized = false - name = "Field 3 new field" - omitted = false - required = true - type = "Integer" - } -} -` - -var testAccContentfulContentTypeLinkConfig = ` -resource "contentful_contenttype" "mycontenttype" { - space_id = "` + spaceID + `" - name = "tf_test1" - description = "Terraform Acc Test Content Type description change" - display_field = "field1" - field { - disabled = false - id = "field1" - localized = false - name = "Field 1 name change" - omitted = false - required = true - type = "Text" - } - field { - disabled = false - id = "field3" - localized = false - name = "Field 3 new field" - omitted = false - required = true - type = "Integer" - } -} - -resource "contentful_contenttype" "mylinked_contenttype" { - space_id = "` + spaceID + `" - name = "tf_linked" - description = "Terraform Acc Test Content Type with links" - display_field = "asset_field" - field { - id = "asset_field" - name = "Asset Field" - type = "Array" - items { - type = "Link" - link_type = "Asset" - } - required = true - } - field { - id = "entry_link_field" - name = "Entry Link Field" - type = "Link" - link_type = "Entry" - validations = [ - jsonencode({ - linkContentType = [ - contentful_contenttype.mycontenttype.id - ] - }) - ] - required = false - } -} -` diff --git a/contentful/resource_contentful_locale.go b/contentful/resource_contentful_locale.go index 86f312e..d257908 100644 --- a/contentful/resource_contentful_locale.go +++ b/contentful/resource_contentful_locale.go @@ -93,7 +93,7 @@ func resourceContentfulLocale() *schema.Resource { } } -func resourceCreateLocale(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { +func resourceCreateLocale(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) var err error @@ -141,11 +141,10 @@ func resourceCreateLocale(ctx context.Context, d *schema.ResourceData, m interfa return nil } -func resourceReadLocale(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { +func resourceReadLocale(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { client := m.(*contentful.Client) - localeID := d.Id() - locale, err := readLocale(d, client, localeID) + locale, err := getLocale(d, client) var notFoundError *contentful.NotFoundError if errors.As(err, ¬FoundError) { @@ -160,12 +159,11 @@ func resourceReadLocale(ctx context.Context, d *schema.ResourceData, m interface return setLocaleProperties(d, locale) } -func resourceUpdateLocale(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { +func resourceUpdateLocale(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) - localeID := d.Id() - locale, err := readLocale(d, client, localeID) + locale, err := getLocale(d, client) if err != nil { return diag.FromErr(err) @@ -207,12 +205,11 @@ func resourceUpdateLocale(ctx context.Context, d *schema.ResourceData, m interfa return setLocaleProperties(d, locale) } -func resourceDeleteLocale(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { +func resourceDeleteLocale(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) - localeID := d.Id() - locale, err := readLocale(d, client, localeID) + locale, err := getLocale(d, client) if err != nil { return diag.FromErr(err) @@ -282,7 +279,7 @@ func setLocaleProperties(d *schema.ResourceData, locale *contentful.Locale) diag return nil } -func readLocale(d *schema.ResourceData, client *contentful.Client, localeID string) (*contentful.Locale, error) { +func getLocale(d *schema.ResourceData, client *contentful.Client) (*contentful.Locale, error) { spaceID := d.Get("space_id").(string) if environment, ok := d.GetOk("environment"); ok { env, envErr := client.Environments.Get(spaceID, environment.(string)) @@ -291,8 +288,8 @@ func readLocale(d *schema.ResourceData, client *contentful.Client, localeID stri return nil, envErr } - return client.Locales.GetWithEnv(env, localeID) + return client.Locales.GetWithEnv(env, d.Id()) } else { - return client.Locales.Get(spaceID, localeID) + return client.Locales.Get(spaceID, d.Id()) } } diff --git a/go.mod b/go.mod index 354ea07..a2d55b2 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,11 @@ module github.com/labd/terraform-provider-contentful go 1.21 require ( + github.com/elliotchance/pie/v2 v2.8.0 github.com/hashicorp/terraform-plugin-docs v0.16.0 + github.com/hashicorp/terraform-plugin-framework v1.4.2 + github.com/hashicorp/terraform-plugin-framework-validators v0.12.0 + github.com/hashicorp/terraform-plugin-mux v0.12.0 github.com/labd/contentful-go v0.5.3 ) @@ -38,7 +42,7 @@ require ( github.com/agext/levenshtein v1.2.3 // indirect github.com/fatih/color v1.15.0 // indirect github.com/golang/protobuf v1.5.3 // indirect - github.com/google/go-cmp v0.5.9 // indirect + github.com/google/go-cmp v0.6.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-checkpoint v0.5.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect @@ -52,7 +56,7 @@ require ( github.com/hashicorp/logutils v1.0.0 // indirect github.com/hashicorp/terraform-exec v0.19.0 // indirect github.com/hashicorp/terraform-json v0.17.1 // indirect - github.com/hashicorp/terraform-plugin-go v0.19.0 // indirect + github.com/hashicorp/terraform-plugin-go v0.19.0 github.com/hashicorp/terraform-plugin-sdk/v2 v2.29.0 github.com/hashicorp/yamux v0.1.1 // indirect github.com/mattn/go-colorable v0.1.13 // indirect @@ -65,10 +69,10 @@ require ( github.com/oklog/run v1.1.0 // indirect github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect github.com/zclconf/go-cty v1.14.0 // indirect - golang.org/x/crypto v0.13.0 // indirect + golang.org/x/crypto v0.14.0 // indirect golang.org/x/mod v0.12.0 // indirect - golang.org/x/net v0.15.0 // indirect - golang.org/x/sys v0.12.0 // indirect + golang.org/x/net v0.17.0 // indirect + golang.org/x/sys v0.13.0 // indirect golang.org/x/text v0.13.0 // indirect google.golang.org/appengine v1.6.8 // indirect google.golang.org/grpc v1.58.1 // indirect @@ -76,4 +80,4 @@ require ( moul.io/http2curl v1.0.1-0.20190925090545-5cd742060b0e // indirect ) -replace github.com/labd/contentful-go v0.5.3 => github.com/flaconi/contentful-go v0.5.3-0.20231024101932-f0a47fb0102a +replace github.com/labd/contentful-go v0.5.3 => github.com/flaconi/contentful-go v0.5.3-0.20231103124131-f3613df0a465 diff --git a/go.sum b/go.sum index 15b7e99..4a91863 100644 --- a/go.sum +++ b/go.sum @@ -33,14 +33,16 @@ github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUK 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/elliotchance/pie/v2 v2.8.0 h1://QS43W8sEha8XV/fjngO5iMudN3XARJV5cpBayAcVY= +github.com/elliotchance/pie/v2 v2.8.0/go.mod h1:18t0dgGFH006g4eVdDtWfgFZPQEgl10IoEO8YWEq3Og= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= -github.com/flaconi/contentful-go v0.5.3-0.20231024101932-f0a47fb0102a h1:gIZXCIHX1mZPue4zR9T8e689OlWW8smL55MdZWWiLXY= -github.com/flaconi/contentful-go v0.5.3-0.20231024101932-f0a47fb0102a/go.mod h1:ciVUTFqeUtSSNjuEQnYLqbXvAlPu/aiPU4CsUc6Ug80= +github.com/flaconi/contentful-go v0.5.3-0.20231103124131-f3613df0a465 h1:GzhBeGqqrF+P63Ijps+lfy2Wzui8Y4t2r07j7zGtDcQ= +github.com/flaconi/contentful-go v0.5.3-0.20231103124131-f3613df0a465/go.mod h1:ciVUTFqeUtSSNjuEQnYLqbXvAlPu/aiPU4CsUc6Ug80= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= @@ -60,8 +62,8 @@ github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= @@ -100,10 +102,16 @@ github.com/hashicorp/terraform-json v0.17.1 h1:eMfvh/uWggKmY7Pmb3T85u86E2EQg6EQH github.com/hashicorp/terraform-json v0.17.1/go.mod h1:Huy6zt6euxaY9knPAFKjUITn8QxUFIe9VuSzb4zn/0o= github.com/hashicorp/terraform-plugin-docs v0.16.0 h1:UmxFr3AScl6Wged84jndJIfFccGyBZn52KtMNsS12dI= github.com/hashicorp/terraform-plugin-docs v0.16.0/go.mod h1:M3ZrlKBJAbPMtNOPwHicGi1c+hZUh7/g0ifT/z7TVfA= +github.com/hashicorp/terraform-plugin-framework v1.4.2 h1:P7a7VP1GZbjc4rv921Xy5OckzhoiO3ig6SGxwelD2sI= +github.com/hashicorp/terraform-plugin-framework v1.4.2/go.mod h1:GWl3InPFZi2wVQmdVnINPKys09s9mLmTZr95/ngLnbY= +github.com/hashicorp/terraform-plugin-framework-validators v0.12.0 h1:HOjBuMbOEzl7snOdOoUfE2Jgeto6JOjLVQ39Ls2nksc= +github.com/hashicorp/terraform-plugin-framework-validators v0.12.0/go.mod h1:jfHGE/gzjxYz6XoUwi/aYiiKrJDeutQNUtGQXkaHklg= github.com/hashicorp/terraform-plugin-go v0.19.0 h1:BuZx/6Cp+lkmiG0cOBk6Zps0Cb2tmqQpDM3iAtnhDQU= github.com/hashicorp/terraform-plugin-go v0.19.0/go.mod h1:EhRSkEPNoylLQntYsk5KrDHTZJh9HQoumZXbOGOXmec= github.com/hashicorp/terraform-plugin-log v0.9.0 h1:i7hOA+vdAItN1/7UrfBqBwvYPQ9TFvymaRGZED3FCV0= github.com/hashicorp/terraform-plugin-log v0.9.0/go.mod h1:rKL8egZQ/eXSyDqzLUuwUYLVdlYeamldAHSxjUFADow= +github.com/hashicorp/terraform-plugin-mux v0.12.0 h1:TJlmeslQ11WlQtIFAfth0vXx+gSNgvMEng2Rn9z3WZY= +github.com/hashicorp/terraform-plugin-mux v0.12.0/go.mod h1:8MR0AgmV+Q03DIjyrAKxXyYlq2EUnYBQP8gxAAA0zeM= github.com/hashicorp/terraform-plugin-sdk/v2 v2.29.0 h1:wcOKYwPI9IorAJEBLzgclh3xVolO7ZorYd6U1vnok14= github.com/hashicorp/terraform-plugin-sdk/v2 v2.29.0/go.mod h1:qH/34G25Ugdj5FcM95cSoXzUgIbgfhVLXCcEcYaMwq8= github.com/hashicorp/terraform-registry-address v0.2.2 h1:lPQBg403El8PPicg/qONZJDC6YlgCVbWDtNmmZKtBno= @@ -210,8 +218,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= -golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck= -golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= +golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= @@ -225,8 +233,8 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= -golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8= -golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -247,15 +255,15 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= -golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= -golang.org/x/term v0.12.0 h1:/ZfYdc3zq+q02Rv9vGqTeSItdzZTSNDmfTi0mBAuidU= -golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= +golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= +golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= diff --git a/internal/acctest/acctest.go b/internal/acctest/acctest.go new file mode 100644 index 0000000..fdbfab6 --- /dev/null +++ b/internal/acctest/acctest.go @@ -0,0 +1,19 @@ +package acctest + +import ( + "os" + "testing" +) + +func TestAccPreCheck(t *testing.T) { + requiredEnvs := []string{ + "CONTENTFUL_MANAGEMENT_TOKEN", + "CONTENTFUL_ORGANIZATION_ID", + "CONTENTFUL_SPACE_ID", + } + for _, val := range requiredEnvs { + if os.Getenv(val) == "" { + t.Fatalf("%v must be set for acceptance tests", val) + } + } +} diff --git a/internal/acctest/client.go b/internal/acctest/client.go new file mode 100644 index 0000000..4ad62c7 --- /dev/null +++ b/internal/acctest/client.go @@ -0,0 +1,16 @@ +package acctest + +import ( + "github.com/labd/contentful-go" + "os" +) + +func GetClient() *contentful.Client { + cmaToken := os.Getenv("CONTENTFUL_MANAGEMENT_TOKEN") + organizationId := os.Getenv("CONTENTFUL_ORGANIZATION_ID") + cma := contentful.NewCMA(cmaToken) + cma.SetOrganization(organizationId) + + //cma.Debug = true + return cma +} diff --git a/internal/custommodifier/booldefault.go b/internal/custommodifier/booldefault.go new file mode 100644 index 0000000..dd05fc3 --- /dev/null +++ b/internal/custommodifier/booldefault.go @@ -0,0 +1,40 @@ +package custommodifier + +import ( + "context" + "fmt" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +// From https://developer.hashicorp.com/terraform/plugin/framework/resources/plan-modification#creating-attribute-plan-modifiers + +var _ planmodifier.Bool = boolDefaultModifier{} +var _ planmodifier.Describer = boolDefaultModifier{} + +type boolDefaultModifier struct { + Default bool +} + +// Description returns a human-readable description of the plan modifier. +func (m boolDefaultModifier) Description(_ context.Context) string { + return fmt.Sprintf("If value is not configured, defaults to %t", m.Default) +} + +// MarkdownDescription returns a markdown description of the plan modifier. +func (m boolDefaultModifier) MarkdownDescription(_ context.Context) string { + return fmt.Sprintf("If value is not configured, defaults to `%t`", m.Default) +} + +func (m boolDefaultModifier) PlanModifyBool(_ context.Context, _ planmodifier.BoolRequest, resp *planmodifier.BoolResponse) { + // If the value is unknown or known, do not set default value. + if resp.PlanValue.IsNull() || resp.PlanValue.IsUnknown() { + resp.PlanValue = types.BoolValue(m.Default) + } +} + +func BoolDefault(defaultValue bool) planmodifier.Bool { + return boolDefaultModifier{ + Default: defaultValue, + } +} diff --git a/internal/custommodifier/int64default.go b/internal/custommodifier/int64default.go new file mode 100644 index 0000000..980f21a --- /dev/null +++ b/internal/custommodifier/int64default.go @@ -0,0 +1,40 @@ +package custommodifier + +import ( + "context" + "fmt" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +// From https://developer.hashicorp.com/terraform/plugin/framework/resources/plan-modification#creating-attribute-plan-modifiers + +var _ planmodifier.Int64 = int64DefaultModifier{} +var _ planmodifier.Describer = int64DefaultModifier{} + +type int64DefaultModifier struct { + Default int64 +} + +// Description returns a human-readable description of the plan modifier. +func (m int64DefaultModifier) Description(_ context.Context) string { + return fmt.Sprintf("If value is not configured, defaults to %d", m.Default) +} + +// MarkdownDescription returns a markdown description of the plan modifier. +func (m int64DefaultModifier) MarkdownDescription(_ context.Context) string { + return fmt.Sprintf("If value is not configured, defaults to `%d`", m.Default) +} + +func (m int64DefaultModifier) PlanModifyInt64(_ context.Context, _ planmodifier.Int64Request, resp *planmodifier.Int64Response) { + // If the value is unknown or known, do not set default value. + if resp.PlanValue.IsNull() || resp.PlanValue.IsUnknown() { + resp.PlanValue = types.Int64Value(m.Default) + } +} + +func Int64Default(defaultValue int64) planmodifier.Int64 { + return int64DefaultModifier{ + Default: defaultValue, + } +} diff --git a/internal/customvalidator/stringallowedwhensetvalidator.go b/internal/customvalidator/stringallowedwhensetvalidator.go new file mode 100644 index 0000000..1014d8b --- /dev/null +++ b/internal/customvalidator/stringallowedwhensetvalidator.go @@ -0,0 +1,101 @@ +package customvalidator + +import ( + "context" + "fmt" + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +var _ validator.String = &stringAllowedWhenSetValidator{} + +type stringAllowedWhenSetValidator struct { + expression path.Expression + widgetType string +} + +func (s stringAllowedWhenSetValidator) Description(_ context.Context) string { + return fmt.Sprintf("Can only be configured for widget.id of type %s", s.widgetType) +} + +func (s stringAllowedWhenSetValidator) MarkdownDescription(ctx context.Context) string { + return s.Description(ctx) +} + +func (s stringAllowedWhenSetValidator) ValidateString(ctx context.Context, request validator.StringRequest, response *validator.StringResponse) { + // If the current attribute configuration is null or unknown, there + // cannot be any value comparisons, so exit early without error. + if request.ConfigValue.IsNull() || request.ConfigValue.IsUnknown() { + return + } + + // Combine the given path expressions with the current attribute path + // expression. This call automatically handles relative and absolute + // expressions. + expression := request.PathExpression.Merge(s.expression) + + // Find paths matching the expression in the configuration data. + matchedPaths, diags := request.Config.PathMatches(ctx, expression) + + response.Diagnostics.Append(diags...) + + // Collect all errors + if diags.HasError() { + return + } + + for _, matchedPath := range matchedPaths { + var matchedPathValue attr.Value + + diags = request.Config.GetAttribute(ctx, matchedPath, &matchedPathValue) + + response.Diagnostics.Append(diags...) + + // Collect all errors + if diags.HasError() { + continue + } + + // If the matched path value is null or unknown, we cannot compare + // values, so continue to other matched paths. + if matchedPathValue.IsNull() || matchedPathValue.IsUnknown() { + continue + } + + // Now that we know the matched path value is not null or unknown, + // it is safe to attempt converting it to the intended attr.Value + // implementation, in this case a types.Int64 value. + var matchedPathConfig types.String + + diags = tfsdk.ValueAs(ctx, matchedPathValue, &matchedPathConfig) + + response.Diagnostics.Append(diags...) + + // If the matched path value was not able to be converted from + // attr.Value to the intended types.Int64 implementation, it most + // likely means that the path expression was not pointing at a + // types.Int64Type attribute. Collect the error and continue to + // other matched paths. + if diags.HasError() { + continue + } + + if matchedPathConfig.ValueString() != s.widgetType { + response.Diagnostics.AddAttributeError( + request.Path, + "Invalid Attribute Value", + fmt.Sprintf("This value can only be set if the widget_id is \"%s\" but it is \"%s\". Path: %s", s.widgetType, matchedPathConfig.ValueString(), request.Path.String()), + ) + } + } +} + +func StringAllowedWhenSetValidator(expression path.Expression, widgetType string) validator.String { + return stringAllowedWhenSetValidator{ + expression: expression, + widgetType: widgetType, + } +} diff --git a/internal/provider/provider.go b/internal/provider/provider.go new file mode 100644 index 0000000..25e7ab6 --- /dev/null +++ b/internal/provider/provider.go @@ -0,0 +1,110 @@ +package provider + +import ( + "context" + "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-framework/provider" + "github.com/hashicorp/terraform-plugin-framework/provider/schema" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/labd/contentful-go" + "github.com/labd/terraform-provider-contentful/internal/resources/contenttype" + "github.com/labd/terraform-provider-contentful/internal/utils" + "os" +) + +var ( + _ provider.Provider = &contentfulProvider{} +) + +func New(version string, debug bool) provider.Provider { + return &contentfulProvider{ + version: version, + debug: debug, + } +} + +type contentfulProvider struct { + version string + debug bool +} + +// Provider schema struct +type contentfulProviderModel struct { + CmaToken types.String `tfsdk:"cma_token"` + OrganizationId types.String `tfsdk:"organization_id"` +} + +func (c contentfulProvider) Metadata(_ context.Context, _ provider.MetadataRequest, response *provider.MetadataResponse) { + response.TypeName = "contentful" +} + +func (c contentfulProvider) Schema(_ context.Context, _ provider.SchemaRequest, response *provider.SchemaResponse) { + response.Schema = schema.Schema{ + Attributes: map[string]schema.Attribute{ + "cma_token": schema.StringAttribute{ + Optional: true, + Sensitive: true, + Description: "The Contentful Management API token", + }, + "organization_id": schema.StringAttribute{ + Optional: true, + Sensitive: true, + Description: "The organization ID", + }, + }, + } +} + +func (c contentfulProvider) Configure(ctx context.Context, request provider.ConfigureRequest, response *provider.ConfigureResponse) { + var config contentfulProviderModel + + diags := request.Config.Get(ctx, &config) + response.Diagnostics.Append(diags...) + + if response.Diagnostics.HasError() { + return + } + + var cmaToken string + + if config.CmaToken.IsUnknown() || config.CmaToken.IsNull() { + cmaToken = os.Getenv("CONTENTFUL_MANAGEMENT_TOKEN") + } else { + cmaToken = config.CmaToken.ValueString() + } + + var organizationId string + + if config.OrganizationId.IsUnknown() || config.OrganizationId.IsNull() { + organizationId = os.Getenv("CONTENTFUL_ORGANIZATION_ID") + } else { + organizationId = config.OrganizationId.ValueString() + } + + cma := contentful.NewCMA(cmaToken) + cma.SetOrganization(organizationId) + + cma.Debug = c.debug + + if os.Getenv("TF_LOG") != "" { + cma.Debug = true + } + + data := utils.ProviderData{ + Client: cma, + } + + response.ResourceData = data + response.DataSourceData = data +} + +func (c contentfulProvider) DataSources(_ context.Context) []func() datasource.DataSource { + return []func() datasource.DataSource{} +} + +func (c contentfulProvider) Resources(_ context.Context) []func() resource.Resource { + return []func() resource.Resource{ + contenttype.NewContentTypeResource, + } +} diff --git a/internal/resources/contenttype/model.go b/internal/resources/contenttype/model.go new file mode 100644 index 0000000..b3f95f9 --- /dev/null +++ b/internal/resources/contenttype/model.go @@ -0,0 +1,773 @@ +package contenttype + +import ( + "errors" + "fmt" + "github.com/elliotchance/pie/v2" + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/labd/contentful-go" + "github.com/labd/terraform-provider-contentful/internal/utils" + "reflect" +) + +// ContentType is the main resource schema data +type ContentType struct { + ID types.String `tfsdk:"id"` + SpaceId types.String `tfsdk:"space_id"` + Environment types.String `tfsdk:"environment"` + Name types.String `tfsdk:"name"` + DisplayField types.String `tfsdk:"display_field"` + Description types.String `tfsdk:"description"` + Version types.Int64 `tfsdk:"version"` + VersionControls types.Int64 `tfsdk:"version_controls"` + Fields []Field `tfsdk:"fields"` + ManageFieldControls types.Bool `tfsdk:"manage_field_controls"` +} + +type Field struct { + Id types.String `tfsdk:"id"` + Name types.String `tfsdk:"name"` + Type types.String `tfsdk:"type"` + LinkType types.String `tfsdk:"link_type"` + Required types.Bool `tfsdk:"required"` + Localized types.Bool `tfsdk:"localized"` + Disabled types.Bool `tfsdk:"disabled"` + Omitted types.Bool `tfsdk:"omitted"` + Validations []Validation `tfsdk:"validations"` + Items *Items `tfsdk:"items"` + Control *Control `tfsdk:"control"` + DefaultValue *DefaultValue `tfsdk:"default_value"` +} + +type DefaultValue struct { + Bool types.Map `tfsdk:"bool"` + String types.Map `tfsdk:"string"` +} + +type Control struct { + WidgetId types.String `tfsdk:"widget_id"` + WidgetNamespace types.String `tfsdk:"widget_namespace"` + Settings *Settings `tfsdk:"settings"` +} + +type Validation struct { + Unique types.Bool `tfsdk:"unique"` + Size *Size `tfsdk:"size"` + Range *Size `tfsdk:"range"` + AssetFileSize *Size `tfsdk:"asset_file_size"` + Regexp *Regexp `tfsdk:"regexp"` + LinkContentType []types.String `tfsdk:"link_content_type"` + LinkMimetypeGroup []types.String `tfsdk:"link_mimetype_group"` + In []types.String `tfsdk:"in"` + EnabledMarks []types.String `tfsdk:"enabled_marks"` + EnabledNodeTypes []types.String `tfsdk:"enabled_node_types"` + Message types.String `tfsdk:"message"` +} + +func (v Validation) Draft() contentful.FieldValidation { + + if !v.Unique.IsUnknown() && !v.Unique.IsNull() { + return contentful.FieldValidationUnique{ + Unique: v.Unique.ValueBool(), + } + } + + if v.Size != nil { + return contentful.FieldValidationSize{ + Size: &contentful.MinMax{ + Min: v.Size.Min.ValueFloat64Pointer(), + Max: v.Size.Max.ValueFloat64Pointer(), + }, + ErrorMessage: v.Message.ValueStringPointer(), + } + } + + if v.Range != nil { + return contentful.FieldValidationRange{ + Range: &contentful.MinMax{ + Min: v.Range.Min.ValueFloat64Pointer(), + Max: v.Range.Max.ValueFloat64Pointer(), + }, + ErrorMessage: v.Message.ValueString(), + } + } + + if v.AssetFileSize != nil { + return contentful.FieldValidationFileSize{ + Size: &contentful.MinMax{ + Min: v.AssetFileSize.Min.ValueFloat64Pointer(), + Max: v.AssetFileSize.Max.ValueFloat64Pointer(), + }, + } + } + + if v.Regexp != nil { + return contentful.FieldValidationRegex{ + Regex: &contentful.Regex{ + Pattern: v.Regexp.Pattern.ValueString(), + }, + ErrorMessage: v.Message.ValueStringPointer(), + } + } + + if len(v.LinkContentType) > 0 { + return contentful.FieldValidationLink{ + LinkContentType: pie.Map(v.LinkContentType, func(t types.String) string { + return t.ValueString() + }), + } + } + + if len(v.LinkMimetypeGroup) > 0 { + return contentful.FieldValidationMimeType{ + MimeTypes: pie.Map(v.LinkMimetypeGroup, func(t types.String) string { + return t.ValueString() + }), + ErrorMessage: v.Message.ValueStringPointer(), + } + } + + if len(v.In) > 0 { + return contentful.FieldValidationPredefinedValues{ + In: pie.Map(v.In, func(t types.String) interface{} { + return t.ValueString() + }), + } + } + + if len(v.EnabledMarks) > 0 { + return contentful.FieldValidationEnabledMarks{ + Marks: pie.Map(v.EnabledMarks, func(t types.String) string { + return t.ValueString() + }), + ErrorMessage: v.Message.ValueStringPointer(), + } + } + + if len(v.EnabledNodeTypes) > 0 { + return contentful.FieldValidationEnabledNodeTypes{ + NodeTypes: pie.Map(v.EnabledNodeTypes, func(t types.String) string { + return t.ValueString() + }), + ErrorMessage: v.Message.ValueStringPointer(), + } + } + + return nil +} + +type Size struct { + Min types.Float64 `tfsdk:"min"` + Max types.Float64 `tfsdk:"max"` +} + +type Regexp struct { + Pattern types.String `tfsdk:"pattern"` +} + +func (f *Field) Equal(n *contentful.Field) bool { + + if n.Type != f.Type.ValueString() { + return false + } + + if n.ID != f.Id.ValueString() { + return false + } + + if n.Name != f.Name.ValueString() { + return false + } + + if n.LinkType != f.LinkType.ValueString() { + return false + } + + if n.Required != f.Required.ValueBool() { + return false + } + + if n.Omitted != f.Omitted.ValueBool() { + return false + } + + if n.Disabled != f.Disabled.ValueBool() { + return false + } + + if n.Localized != f.Localized.ValueBool() { + return false + } + + if f.Items == nil && n.Items != nil { + return false + } + + if f.Items != nil && !f.Items.Equal(n.Items) { + return false + } + + if len(f.Validations) != len(n.Validations) { + return false + } + + for idx, validation := range pie.Map(f.Validations, func(t Validation) contentful.FieldValidation { + return t.Draft() + }) { + cfVal := n.Validations[idx] + + if !reflect.DeepEqual(validation, cfVal) { + return false + } + + } + + return true +} + +func (f *Field) ToNative() (*contentful.Field, error) { + + contentfulField := &contentful.Field{ + ID: f.Id.ValueString(), + Name: f.Name.ValueString(), + Type: f.Type.ValueString(), + Localized: f.Localized.ValueBool(), + Required: f.Required.ValueBool(), + Disabled: f.Disabled.ValueBool(), + Omitted: f.Omitted.ValueBool(), + Validations: pie.Map(f.Validations, func(t Validation) contentful.FieldValidation { + return t.Draft() + }), + } + + if !f.LinkType.IsNull() && !f.LinkType.IsUnknown() { + contentfulField.LinkType = f.LinkType.ValueString() + } + + if contentfulField.Type == contentful.FieldTypeArray { + items, errItem := f.Items.ToNative() + + if errItem != nil { + return nil, errItem + } + + contentfulField.Items = items + } + + return contentfulField, nil +} + +func getTypeOfMap(mapValues map[string]any) (*string, error) { + for _, v := range mapValues { + switch c := v.(type) { + case string: + t := "string" + return &t, nil + case bool: + t := "bool" + return &t, nil + default: + return nil, errors.New(fmt.Sprintf("The default type %T is not supported by the provider", c)) + } + } + + return nil, nil +} + +func (f *Field) Import(n *contentful.Field, c []contentful.Controls) error { + f.Id = types.StringValue(n.ID) + f.Name = types.StringValue(n.Name) + f.Type = types.StringValue(n.Type) + f.LinkType = utils.FromOptionalString(n.LinkType) + f.Required = types.BoolValue(n.Required) + f.Omitted = types.BoolValue(n.Omitted) + f.Localized = types.BoolValue(n.Localized) + f.Disabled = types.BoolValue(n.Disabled) + + defaultValueType, err := getTypeOfMap(n.DefaultValue) + + if err != nil { + return err + } + + if defaultValueType != nil { + + f.DefaultValue = &DefaultValue{ + Bool: types.MapNull(types.BoolType), + String: types.MapNull(types.StringType), + } + + switch *defaultValueType { + case "string": + stringMap := map[string]attr.Value{} + + for k, v := range n.DefaultValue { + stringMap[k] = types.StringValue(v.(string)) + } + + f.DefaultValue.String = types.MapValueMust(types.StringType, stringMap) + case "bool": + boolMap := map[string]attr.Value{} + + for k, v := range n.DefaultValue { + boolMap[k] = types.BoolValue(v.(bool)) + } + + f.DefaultValue.Bool = types.MapValueMust(types.BoolType, boolMap) + } + + } + + validations, err := getValidations(n.Validations) + + if err != nil { + return err + } + + f.Validations = validations + + if n.Type == contentful.FieldTypeArray { + + itemValidations, err := getValidations(n.Items.Validations) + + if err != nil { + return err + } + + f.Items = &Items{ + Type: types.StringValue(n.Items.Type), + LinkType: types.StringPointerValue(n.Items.LinkType), + Validations: itemValidations, + } + } + + idx := pie.FindFirstUsing(c, func(control contentful.Controls) bool { + return n.ID == control.FieldID + }) + + if idx != -1 && c[idx].WidgetID != nil { + + var settings *Settings + + if c[idx].Settings != nil { + settings = &Settings{} + + settings.Import(c[idx].Settings) + } + if val, ok := c[idx].Settings["helpText"]; ok { + settings.HelpText = types.StringValue(val) + } + + f.Control = &Control{ + WidgetId: types.StringPointerValue(c[idx].WidgetID), + WidgetNamespace: types.StringPointerValue(c[idx].WidgetNameSpace), + Settings: settings, + } + } + + return nil +} + +type Settings struct { + HelpText types.String `tfsdk:"help_text"` + TrueLabel types.String `tfsdk:"true_label"` + FalseLabel types.String `tfsdk:"false_label"` + Stars types.String `tfsdk:"stars"` + Format types.String `tfsdk:"format"` + TimeFormat types.String `tfsdk:"ampm"` +} + +func (s *Settings) Import(settings map[string]string) { + if val, ok := settings["helpText"]; ok { + s.HelpText = types.StringValue(val) + } + + if val, ok := settings["trueLabel"]; ok { + s.TrueLabel = types.StringValue(val) + } + + if val, ok := settings["falseLabel"]; ok { + s.FalseLabel = types.StringValue(val) + } + + if val, ok := settings["stars"]; ok { + s.Stars = types.StringValue(val) + } + + if val, ok := settings["format"]; ok { + s.Format = types.StringValue(val) + } + + if val, ok := settings["ampm"]; ok { + s.TimeFormat = types.StringValue(val) + } +} + +func (s *Settings) Draft() map[string]string { + settings := make(map[string]string) + + addValue(s.HelpText, "helpText", settings) + addValue(s.Format, "format", settings) + addValue(s.Stars, "stars", settings) + addValue(s.FalseLabel, "falseLabel", settings) + addValue(s.TrueLabel, "trueLabel", settings) + addValue(s.TimeFormat, "ampm", settings) + + return settings +} + +func addValue(val types.String, key string, settings map[string]string) { + if !val.IsUnknown() && !val.IsNull() { + settings[key] = val.ValueString() + } +} + +type Items struct { + Type types.String `tfsdk:"type"` + LinkType types.String `tfsdk:"link_type"` + Validations []Validation `tfsdk:"validations"` +} + +func (i *Items) ToNative() (*contentful.FieldTypeArrayItem, error) { + + return &contentful.FieldTypeArrayItem{ + Type: i.Type.ValueString(), + Validations: pie.Map(i.Validations, func(t Validation) contentful.FieldValidation { + return t.Draft() + }), + LinkType: i.LinkType.ValueStringPointer(), + }, nil +} + +func (i *Items) Equal(n *contentful.FieldTypeArrayItem) bool { + + if n == nil { + return false + } + + if i.Type.ValueString() != n.Type { + return false + } + + if !compareStringPointer(i.LinkType, n.LinkType) { + return false + } + + if len(i.Validations) != len(n.Validations) { + return false + } + + for idx, validation := range pie.Map(i.Validations, func(t Validation) contentful.FieldValidation { + return t.Draft() + }) { + cfVal := n.Validations[idx] + + if !reflect.DeepEqual(validation, cfVal) { + return false + } + + } + + return true +} + +func (c *ContentType) Draft() (*contentful.ContentType, error) { + + var fields []*contentful.Field + + for _, field := range c.Fields { + + nativeField, err := field.ToNative() + if err != nil { + return nil, err + } + + fields = append(fields, nativeField) + } + + contentfulType := &contentful.ContentType{ + Name: c.Name.ValueString(), + DisplayField: c.DisplayField.ValueString(), + Fields: fields, + } + + if !c.Description.IsNull() && !c.Description.IsUnknown() { + contentfulType.Description = c.Description.ValueStringPointer() + } + + return contentfulType, nil + +} + +func (c *ContentType) Import(n *contentful.ContentType, e *contentful.EditorInterface) error { + c.ID = types.StringValue(n.Sys.ID) + c.Version = types.Int64Value(int64(n.Sys.Version)) + + c.Description = types.StringPointerValue(n.Description) + + c.Name = types.StringValue(n.Name) + c.DisplayField = types.StringValue(n.DisplayField) + + var fields []Field + + var controls []contentful.Controls + + if e != nil { + controls = e.Controls + c.VersionControls = types.Int64Value(int64(e.Sys.Version)) + } + + for _, nf := range n.Fields { + field := &Field{} + err := field.Import(nf, controls) + if err != nil { + return err + } + fields = append(fields, *field) + } + + c.Fields = fields + + return nil + +} + +func compareStringPointer(tfPointer types.String, cfPointer *string) bool { + if cfPointer != nil && tfPointer.ValueStringPointer() == nil { + return false + } + + if tfPointer.ValueStringPointer() != nil { + + if cfPointer == nil { + return false + } + + if tfPointer.ValueString() != *cfPointer { + return false + } + } + + return true +} + +func (c *ContentType) Equal(n *contentful.ContentType) bool { + + if !compareStringPointer(c.Description, n.Description) { + return false + } + + if c.Name.ValueString() != n.Name { + return false + } + + if c.DisplayField.ValueString() != n.DisplayField { + return false + } + + if len(c.Fields) != len(n.Fields) { + return false + } + + for _, field := range c.Fields { + idx := pie.FindFirstUsing(n.Fields, func(f *contentful.Field) bool { + return f.ID == field.Id.ValueString() + }) + + if idx == -1 { + return false + } + + if !field.Equal(n.Fields[idx]) { + return false + } + } + + return true +} + +func (c *ContentType) EqualControls(n []contentful.Controls) bool { + + if len(c.Fields) != len(n) { + return false + } + + filteredControls := pie.Filter(n, func(c contentful.Controls) bool { + return c.WidgetID != nil || c.WidgetNameSpace != nil || c.Settings != nil + }) + + filteredFields := pie.Filter(c.Fields, func(f Field) bool { + return f.Control != nil + }) + + if len(filteredControls) != len(filteredFields) { + return false + } + + for _, field := range filteredFields { + idx := pie.FindFirstUsing(filteredControls, func(t contentful.Controls) bool { + return t.FieldID == field.Id.ValueString() + }) + + if idx == -1 { + return false + } + control := filteredControls[idx] + + if field.Control.WidgetId.ValueString() != *control.WidgetID { + return false + } + + if field.Control.WidgetNamespace.ValueString() != *control.WidgetNameSpace { + return false + } + + if field.Control.Settings == nil && control.Settings != nil { + return false + } + + if field.Control.Settings != nil && !reflect.DeepEqual(field.Control.Settings.Draft(), control.Settings) { + return false + } + } + + return true +} + +func (c *ContentType) DraftControls() []contentful.Controls { + return pie.Map(c.Fields, func(field Field) contentful.Controls { + + control := contentful.Controls{ + FieldID: field.Id.ValueString(), + } + + if field.Control != nil { + control.WidgetID = field.Control.WidgetId.ValueStringPointer() + control.WidgetNameSpace = field.Control.WidgetNamespace.ValueStringPointer() + + if field.Control.Settings != nil { + control.Settings = field.Control.Settings.Draft() + } + } + + return control + + }) +} + +func getValidations(contentfulValidations []contentful.FieldValidation) ([]Validation, error) { + var validations []Validation + + for _, validation := range contentfulValidations { + + val, err := getValidation(validation) + + if err != nil { + return nil, err + } + + validations = append(validations, *val) + } + + return validations, nil +} + +func getValidation(cfVal contentful.FieldValidation) (*Validation, error) { + + if v, ok := cfVal.(contentful.FieldValidationPredefinedValues); ok { + + return &Validation{ + In: pie.Map(v.In, func(t any) types.String { + return types.StringValue(t.(string)) + }), + }, nil + } + + if v, ok := cfVal.(contentful.FieldValidationUnique); ok { + + return &Validation{ + Unique: types.BoolValue(v.Unique), + }, nil + } + + if v, ok := cfVal.(contentful.FieldValidationRegex); ok { + + return &Validation{ + Regexp: &Regexp{ + Pattern: types.StringValue(v.Regex.Pattern), + }, + Message: types.StringPointerValue(v.ErrorMessage), + }, nil + } + + if v, ok := cfVal.(contentful.FieldValidationSize); ok { + + return &Validation{ + Size: &Size{ + Max: types.Float64PointerValue(v.Size.Max), + Min: types.Float64PointerValue(v.Size.Min), + }, + }, nil + } + + if v, ok := cfVal.(contentful.FieldValidationLink); ok { + + return &Validation{ + LinkContentType: pie.Map(v.LinkContentType, func(t string) types.String { + return types.StringValue(t) + }), + }, nil + } + + if v, ok := cfVal.(contentful.FieldValidationMimeType); ok { + + return &Validation{ + LinkMimetypeGroup: pie.Map(v.MimeTypes, func(t string) types.String { + return types.StringValue(t) + }), + Message: types.StringPointerValue(v.ErrorMessage), + }, nil + } + + if v, ok := cfVal.(contentful.FieldValidationRange); ok { + + return &Validation{ + Range: &Size{ + Max: types.Float64PointerValue(v.Range.Max), + Min: types.Float64PointerValue(v.Range.Min), + }, + }, nil + } + + if v, ok := cfVal.(contentful.FieldValidationEnabledNodeTypes); ok { + + return &Validation{ + EnabledNodeTypes: pie.Map(v.NodeTypes, func(t string) types.String { + return types.StringValue(t) + }), + Message: types.StringPointerValue(v.ErrorMessage), + }, nil + } + + if v, ok := cfVal.(contentful.FieldValidationEnabledMarks); ok { + + return &Validation{ + EnabledMarks: pie.Map(v.Marks, func(t string) types.String { + return types.StringValue(t) + }), + Message: types.StringPointerValue(v.ErrorMessage), + }, nil + } + + if v, ok := cfVal.(contentful.FieldValidationFileSize); ok { + return &Validation{ + AssetFileSize: &Size{ + Max: types.Float64PointerValue(v.Size.Max), + Min: types.Float64PointerValue(v.Size.Min), + }, + }, nil + } + + return nil, errors.New(fmt.Sprintf("Unsupported validation used, %s. Please implement", reflect.TypeOf(cfVal).String())) +} diff --git a/internal/resources/contenttype/resource.go b/internal/resources/contenttype/resource.go new file mode 100644 index 0000000..57f0189 --- /dev/null +++ b/internal/resources/contenttype/resource.go @@ -0,0 +1,718 @@ +package contenttype + +import ( + "context" + "fmt" + "github.com/elliotchance/pie/v2" + "github.com/hashicorp/terraform-plugin-framework-validators/listvalidator" + "github.com/hashicorp/terraform-plugin-framework-validators/objectvalidator" + "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/objectplanmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/labd/contentful-go" + "github.com/labd/terraform-provider-contentful/internal/custommodifier" + "github.com/labd/terraform-provider-contentful/internal/customvalidator" + "github.com/labd/terraform-provider-contentful/internal/utils" + "reflect" + "strings" +) + +const ( + OnlyControlVersion = "onlyControlVersion" +) + +// Ensure the implementation satisfies the expected interfaces. +var ( + _ resource.Resource = &contentTypeResource{} + _ resource.ResourceWithConfigure = &contentTypeResource{} + _ resource.ResourceWithImportState = &contentTypeResource{} +) + +func NewContentTypeResource() resource.Resource { + return &contentTypeResource{} +} + +// contentTypeResource is the resource implementation. +type contentTypeResource struct { + client *contentful.Client +} + +func (e *contentTypeResource) Metadata(_ context.Context, request resource.MetadataRequest, response *resource.MetadataResponse) { + response.TypeName = request.ProviderTypeName + "_contenttype" +} + +var contentfulTypes = []string{ + "Symbol", + "Text", + "RichText", + "Integer", + "Number", + "Date", + "Boolean", + "Object", + "Location", + "Array", + "Link", + "ResourceLink", +} + +var linkTypes = []string{"Asset", "Entry"} +var resourcelinkTypes = []string{"Contentful:Entry"} +var arrayItemTypes = []string{"Symbol", "Link", "Resourcelink"} + +//https://www.contentful.com/developers/docs/extensibility/app-framework/editor-interfaces/ + +func (e *contentTypeResource) Schema(ctx context.Context, request resource.SchemaRequest, response *resource.SchemaResponse) { + + sizeSchema := schema.SingleNestedAttribute{ + Optional: true, + Attributes: map[string]schema.Attribute{ + "min": schema.Float64Attribute{ + Optional: true, + }, + "max": schema.Float64Attribute{ + Optional: true, + }, + }, + } + + validationsSchema := schema.ListNestedAttribute{ + Optional: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "range": sizeSchema, + "size": sizeSchema, + "unique": schema.BoolAttribute{ + Optional: true, + }, + "asset_file_size": sizeSchema, + "regexp": schema.SingleNestedAttribute{ + Optional: true, + Attributes: map[string]schema.Attribute{ + "pattern": schema.StringAttribute{ + Optional: true, + }, + }, + }, + "link_mimetype_group": schema.ListAttribute{ + Optional: true, + ElementType: types.StringType, + }, + "link_content_type": schema.ListAttribute{ + Optional: true, + ElementType: types.StringType, + }, + "in": schema.ListAttribute{ + Optional: true, + ElementType: types.StringType, + }, + "enabled_marks": schema.ListAttribute{ + Optional: true, + ElementType: types.StringType, + }, + "enabled_node_types": schema.ListAttribute{ + Optional: true, + ElementType: types.StringType, + }, + "message": schema.StringAttribute{ + Optional: true, + }, + }, + Validators: []validator.Object{ + objectvalidator.AtLeastOneOf(path.MatchRelative().AtName("range")), + }, + }, + } + + response.Schema = schema.Schema{ + Description: "Todo for explaining contenttype", + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + Computed: true, + Description: "content type id", + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + }, + "version": schema.Int64Attribute{ + Computed: true, + }, + "version_controls": schema.Int64Attribute{ + Computed: true, + }, + "space_id": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + Description: "space id", + }, + "environment": schema.StringAttribute{ + Optional: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + }, + "name": schema.StringAttribute{ + Required: true, + }, + "display_field": schema.StringAttribute{ + Required: true, + }, + "description": schema.StringAttribute{ + Optional: true, + }, + "manage_field_controls": schema.BoolAttribute{ + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Bool{ + custommodifier.BoolDefault(false), + }, + }, + "fields": schema.ListNestedAttribute{ + Validators: []validator.List{ + listvalidator.SizeAtLeast(1), + }, + Required: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + Required: true, + }, + "name": schema.StringAttribute{ + Required: true, + }, + "type": schema.StringAttribute{ + Required: true, + Validators: []validator.String{ + stringvalidator.OneOf(contentfulTypes...), + }, + }, + "link_type": schema.StringAttribute{ + Optional: true, + }, + "required": schema.BoolAttribute{ + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Bool{ + custommodifier.BoolDefault(false), + }, + }, + "localized": schema.BoolAttribute{ + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Bool{ + custommodifier.BoolDefault(false), + }, + }, + "disabled": schema.BoolAttribute{ + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Bool{ + custommodifier.BoolDefault(false), + }, + }, + "omitted": schema.BoolAttribute{ + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Bool{ + custommodifier.BoolDefault(false), + }, + }, + "validations": validationsSchema, + "items": schema.SingleNestedAttribute{ + Optional: true, + PlanModifiers: []planmodifier.Object{ + objectplanmodifier.UseStateForUnknown(), + }, + Attributes: map[string]schema.Attribute{ + "type": schema.StringAttribute{ + Required: true, + Validators: []validator.String{ + stringvalidator.OneOf(contentfulTypes...), + }, + }, + "link_type": schema.StringAttribute{ + Optional: true, + }, + "validations": validationsSchema, + }, + }, + "default_value": schema.SingleNestedAttribute{ + Optional: true, + Attributes: map[string]schema.Attribute{ + "bool": schema.MapAttribute{ + ElementType: types.BoolType, + Optional: true, + }, + "string": schema.MapAttribute{ + ElementType: types.StringType, + Optional: true, + }, + }, + }, + "control": schema.SingleNestedAttribute{ + Optional: true, + PlanModifiers: []planmodifier.Object{ + objectplanmodifier.UseStateForUnknown(), + }, + + Attributes: map[string]schema.Attribute{ + "widget_id": schema.StringAttribute{ + Required: true, + }, + "widget_namespace": schema.StringAttribute{ + Required: true, + Validators: []validator.String{ + stringvalidator.OneOf("builtin", "extension", "app"), + }, + }, + "settings": schema.SingleNestedAttribute{ + Attributes: map[string]schema.Attribute{ + "help_text": schema.StringAttribute{ + Optional: true, + }, + "true_label": schema.StringAttribute{ + Optional: true, + Validators: []validator.String{ + customvalidator.StringAllowedWhenSetValidator(path.MatchRelative().AtParent().AtParent().AtName("widget_id"), "boolean"), + }, + }, + "false_label": schema.StringAttribute{ + Optional: true, + Validators: []validator.String{ + customvalidator.StringAllowedWhenSetValidator(path.MatchRelative().AtParent().AtParent().AtName("widget_id"), "boolean"), + }, + }, + "stars": schema.StringAttribute{ + Optional: true, + Validators: []validator.String{ + customvalidator.StringAllowedWhenSetValidator(path.MatchRelative().AtParent().AtParent().AtName("widget_id"), "rating"), + }, + }, + "format": schema.StringAttribute{ + Optional: true, + Validators: []validator.String{ + stringvalidator.OneOf("dateonly", "time", "timeZ"), + customvalidator.StringAllowedWhenSetValidator(path.MatchRelative().AtParent().AtParent().AtName("widget_id"), "datepicker"), + }, + }, + "ampm": schema.StringAttribute{ + Optional: true, + Validators: []validator.String{ + stringvalidator.OneOf("12", "24"), + customvalidator.StringAllowedWhenSetValidator(path.MatchRelative().AtParent().AtParent().AtName("widget_id"), "datepicker"), + }, + }, + }, + Optional: true, + PlanModifiers: []planmodifier.Object{ + objectplanmodifier.UseStateForUnknown(), + }, + }, + }, + }, + }, + }, + }, + }, + } +} + +func (e *contentTypeResource) Configure(_ context.Context, request resource.ConfigureRequest, _ *resource.ConfigureResponse) { + if request.ProviderData == nil { + return + } + + data := request.ProviderData.(utils.ProviderData) + e.client = data.Client + +} + +func (e *contentTypeResource) Create(ctx context.Context, request resource.CreateRequest, response *resource.CreateResponse) { + var plan ContentType + response.Diagnostics.Append(request.Plan.Get(ctx, &plan)...) + if response.Diagnostics.HasError() { + return + } + + draft, err := plan.Draft() + + if err != nil { + response.Diagnostics.AddError("Error creating contenttype", err.Error()) + return + } + + if plan.Environment.IsUnknown() || plan.Environment.IsNull() { + if err = e.client.ContentTypes.Upsert(plan.SpaceId.ValueString(), draft); err != nil { + response.Diagnostics.AddError("Error creating contenttype", err.Error()) + return + } + + if err = e.client.ContentTypes.Activate(plan.SpaceId.ValueString(), draft); err != nil { + response.Diagnostics.AddError("Error activating contenttype", err.Error()) + return + } + } else { + + env, envErr := e.client.Environments.Get(plan.SpaceId.ValueString(), plan.Environment.ValueString()) + + if envErr != nil { + response.Diagnostics.AddError("Error creating contenttype", envErr.Error()) + return + } + + if err = e.client.ContentTypes.UpsertWithEnv(env, draft); err != nil { + response.Diagnostics.AddError("Error creating contenttype", err.Error()) + return + } + + if err = e.client.ContentTypes.ActivateWithEnv(env, draft); err != nil { + response.Diagnostics.AddError("Error activating contenttype", err.Error()) + return + } + } + + plan.Version = types.Int64Value(int64(draft.Sys.Version)) + plan.VersionControls = types.Int64Value(0) + plan.ID = types.StringValue(draft.Sys.ID) + + // Set state to fully populated data + response.Diagnostics.Append(response.State.Set(ctx, plan)...) + if response.Diagnostics.HasError() { + return + } +} + +func (e *contentTypeResource) Read(ctx context.Context, request resource.ReadRequest, response *resource.ReadResponse) { + // Get current state + var state *ContentType + diags := request.State.Get(ctx, &state) + response.Diagnostics.Append(diags...) + if response.Diagnostics.HasError() { + return + } + + e.doRead(ctx, state, &response.State, &response.Diagnostics) +} + +func (e *contentTypeResource) doRead(ctx context.Context, contentType *ContentType, state *tfsdk.State, d *diag.Diagnostics) { + + contentfulContentType, err := e.getContentType(contentType) + if err != nil { + d.AddError( + "Error reading contenttype", + "Could not retrieve contenttype, unexpected error: "+err.Error(), + ) + return + } + + var controls *contentful.EditorInterface + + if contentType.ManageFieldControls.ValueBool() { + controls, err = e.getContentTypeControls(contentType) + if err != nil { + d.AddError( + "Error reading contenttype", + "Could not retrieve contenttype, unexpected error: "+err.Error(), + ) + return + } + + if u, ok := ctx.Value(OnlyControlVersion).(bool); ok && u { + contentType.VersionControls = types.Int64Value(int64(controls.Sys.Version)) + + draftControls := contentType.DraftControls() + // remove all controls which are not in the plan for an easier import + controls.Controls = pie.Filter(controls.Controls, func(c contentful.Controls) bool { + return pie.Any(draftControls, func(value contentful.Controls) bool { + return value.FieldID == c.FieldID && value.WidgetID != nil && reflect.DeepEqual(value.WidgetID, c.WidgetID) + }) + }) + } + } + + err = contentType.Import(contentfulContentType, controls) + + if err != nil { + d.AddError( + "Error importing contenttype to state", + "Could not import contenttype to state, unexpected error: "+err.Error(), + ) + return + } + + // Set refreshed state + d.Append(state.Set(ctx, &contentType)...) + if d.HasError() { + return + } +} + +func (e *contentTypeResource) Update(ctx context.Context, request resource.UpdateRequest, response *resource.UpdateResponse) { + // Retrieve values from plan + var plan *ContentType + diags := request.Plan.Get(ctx, &plan) + response.Diagnostics.Append(diags...) + if response.Diagnostics.HasError() { + return + } + + // Get current state + var state *ContentType + diags = request.State.Get(ctx, &state) + response.Diagnostics.Append(diags...) + if response.Diagnostics.HasError() { + return + } + + contentfulContentType, err := e.getContentType(plan) + if err != nil { + response.Diagnostics.AddError( + "Error reading contenttype", + "Could not retrieve contenttype, unexpected error: "+err.Error(), + ) + return + } + + deletedFields := pie.Of(pie.FilterNot(contentfulContentType.Fields, func(cf *contentful.Field) bool { + return pie.FindFirstUsing(plan.Fields, func(f Field) bool { + return cf.ID == f.Id.ValueString() + }) != -1 + + })).Map(func(f *contentful.Field) *contentful.Field { + f.Omitted = true + + return f + }).Result + + draft, err := plan.Draft() + + if err != nil { + response.Diagnostics.AddError("Error updating contenttype", err.Error()) + return + } + + draft.Sys = contentfulContentType.Sys + + if len(deletedFields) > 0 { + draft.Fields = append(draft.Fields, deletedFields...) + } + + // To remove a field from a content type 4 API calls need to be made. + // Omit the removed fields and publish the new version of the content type, + // followed by the field removal and final publish. + + if !plan.Equal(contentfulContentType) { + err = e.doUpdate(plan, draft) + if err != nil { + response.Diagnostics.AddError( + "Error updating subscription", + "Could not update subscription, unexpected error: "+err.Error(), + ) + return + } + + if len(deletedFields) > 0 { + sys := draft.Sys + draft, err = plan.Draft() + + if err != nil { + response.Diagnostics.AddError("Error updating contenttype", err.Error()) + return + } + + draft.Sys = sys + + err = e.doUpdate(plan, draft) + if err != nil { + response.Diagnostics.AddError( + "Error updating subscription", + "Could not update subscription, unexpected error: "+err.Error(), + ) + return + } + } + } + + ctxControls := e.updateControls(ctx, state, plan, &response.Diagnostics) + + e.doRead(ctxControls, plan, &response.State, &response.Diagnostics) +} + +func (e *contentTypeResource) updateControls(ctx context.Context, state *ContentType, plan *ContentType, d *diag.Diagnostics) context.Context { + if plan.ManageFieldControls.ValueBool() { + // first import of controls to the state just get the controls version + if state.VersionControls.IsNull() { + return context.WithValue(ctx, OnlyControlVersion, true) + } + + controls, err := e.getContentTypeControls(plan) + if err != nil { + d.AddError( + "Error reading contenttype", + "Could not retrieve contenttype controls, unexpected error: "+err.Error(), + ) + return ctx + } + + if !plan.EqualControls(controls.Controls) { + + controls.Controls = plan.DraftControls() + if !plan.Environment.IsUnknown() && !plan.Environment.IsNull() { + e.client.SetEnvironment(plan.Environment.ValueString()) + } + + if err = e.client.EditorInterfaces.Update(plan.SpaceId.ValueString(), plan.ID.ValueString(), controls); err != nil { + d.AddError( + "Error updating contenttype controls", + "Could not update contenttype controls, unexpected error: "+err.Error(), + ) + + return ctx + } + } + + } + + return ctx +} + +func (e *contentTypeResource) doUpdate(plan *ContentType, draft *contentful.ContentType) error { + if plan.Environment.IsUnknown() || plan.Environment.IsNull() { + + if err := e.client.ContentTypes.Upsert(plan.SpaceId.ValueString(), draft); err != nil { + return err + } + + if err := e.client.ContentTypes.Activate(plan.SpaceId.ValueString(), draft); err != nil { + return err + } + } else { + + env, err := e.client.Environments.Get(plan.SpaceId.ValueString(), plan.Environment.ValueString()) + + if err != nil { + return err + } + + if err = e.client.ContentTypes.UpsertWithEnv(env, draft); err != nil { + return err + } + + if err = e.client.ContentTypes.ActivateWithEnv(env, draft); err != nil { + return err + } + } + return nil +} + +func (e *contentTypeResource) Delete(ctx context.Context, request resource.DeleteRequest, response *resource.DeleteResponse) { + // Get current state + var state *ContentType + response.Diagnostics.Append(request.State.Get(ctx, &state)...) + + contentfulContentType, err := e.getContentType(state) + + if err != nil { + response.Diagnostics.AddError( + "Error reading contenttype", + "Could not retrieve contenttype, unexpected error: "+err.Error(), + ) + return + } + + err = e.doDelete(state, contentfulContentType) + if err != nil { + response.Diagnostics.AddError( + "Error deleting contenttype", + "Could not delete contenttype, unexpected error: "+err.Error(), + ) + return + } + +} + +func (e *contentTypeResource) doDelete(data *ContentType, draft *contentful.ContentType) error { + if data.Environment.IsUnknown() || data.Environment.IsNull() { + + if err := e.client.ContentTypes.Deactivate(data.SpaceId.ValueString(), draft); err != nil { + return err + } + + if err := e.client.ContentTypes.Delete(data.SpaceId.ValueString(), draft); err != nil { + return err + } + } else { + + env, err := e.client.Environments.Get(data.SpaceId.ValueString(), data.Environment.ValueString()) + + if err != nil { + return err + } + + if err = e.client.ContentTypes.DeactivateWithEnv(env, draft); err != nil { + return err + } + + if err = e.client.ContentTypes.DeleteWithEnv(env, draft); err != nil { + return err + } + + } + return nil +} + +func (e *contentTypeResource) ImportState(ctx context.Context, request resource.ImportStateRequest, response *resource.ImportStateResponse) { + idParts := strings.SplitN(request.ID, ":", 3) + + if len(idParts) != 3 || idParts[0] == "" || idParts[1] == "" || idParts[2] == "" { + response.Diagnostics.AddError( + "Unexpected Import Identifier", + fmt.Sprintf("Expected import identifier with format: localeId:env:spaceId. Got: %q", request.ID), + ) + return + } + + futureState := &ContentType{ + ID: types.StringValue(idParts[0]), + SpaceId: types.StringValue(idParts[2]), + Environment: types.StringValue(idParts[1]), + } + + e.doRead(ctx, futureState, &response.State, &response.Diagnostics) +} + +func (e *contentTypeResource) getContentType(editor *ContentType) (*contentful.ContentType, error) { + if !editor.Environment.IsUnknown() && !editor.Environment.IsNull() { + env, err := e.client.Environments.Get(editor.SpaceId.ValueString(), editor.Environment.ValueString()) + + if err != nil { + return nil, err + } + return e.client.ContentTypes.GetWithEnv(env, editor.ID.ValueString()) + } else { + return e.client.ContentTypes.Get(editor.SpaceId.ValueString(), editor.ID.ValueString()) + } +} + +func (e *contentTypeResource) getContentTypeControls(editor *ContentType) (*contentful.EditorInterface, error) { + if !editor.Environment.IsUnknown() && !editor.Environment.IsNull() { + env, err := e.client.Environments.Get(editor.SpaceId.ValueString(), editor.Environment.ValueString()) + + if err != nil { + return nil, err + } + return e.client.EditorInterfaces.GetWithEnv(env, editor.ID.ValueString()) + } else { + return e.client.EditorInterfaces.Get(editor.SpaceId.ValueString(), editor.ID.ValueString()) + } +} diff --git a/internal/resources/contenttype/resource_test.go b/internal/resources/contenttype/resource_test.go new file mode 100644 index 0000000..5b0fc63 --- /dev/null +++ b/internal/resources/contenttype/resource_test.go @@ -0,0 +1,189 @@ +package contenttype_test + +import ( + "errors" + "fmt" + "github.com/hashicorp/terraform-plugin-framework/providerserver" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/labd/contentful-go" + "github.com/labd/terraform-provider-contentful/internal/acctest" + "github.com/labd/terraform-provider-contentful/internal/provider" + "github.com/labd/terraform-provider-contentful/internal/utils" + "os" + + "testing" +) + +func TestContentTypeResource_Create(t *testing.T) { + resourceName := "contentful_contenttype.acctest_content_type" + linkedResourceName := "contentful_contenttype.linked_content_type" + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.TestAccPreCheck(t) }, + CheckDestroy: testAccCheckContentfulContentTypeDestroy, + ProtoV6ProviderFactories: map[string]func() (tfprotov6.ProviderServer, error){ + "contentful": providerserver.NewProtocol6WithError(provider.New("test", false)), + }, + Steps: []resource.TestStep{ + { + Config: testContentType("acctest_content_type", os.Getenv("CONTENTFUL_SPACE_ID")), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "name", "tf_test1"), + resource.TestCheckResourceAttr(resourceName, "version", "2"), + resource.TestCheckResourceAttr(resourceName, "version_controls", "0"), + //todo check in contentful directly if the type looks like this + ), + }, + { + Config: testContentTypeUpdate("acctest_content_type", os.Getenv("CONTENTFUL_SPACE_ID")), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "name", "tf_test1"), + resource.TestCheckResourceAttr(resourceName, "version", "2"), + resource.TestCheckResourceAttr(resourceName, "version_controls", "2"), + //todo check in contentful directly if the type looks like this + ), + }, + { + Config: testContentTypeLinkConfig("acctest_content_type", os.Getenv("CONTENTFUL_SPACE_ID"), "linked_content_type"), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(linkedResourceName, "name", "tf_linked"), + //todo check in contentful directly if the type looks like this + ), + }, + }, + }) +} + +func testAccCheckContentfulContentTypeDestroy(s *terraform.State) (err error) { + client := acctest.GetClient() + + for _, rs := range s.RootModule().Resources { + if rs.Type != "contentful_contenttype" { + continue + } + + spaceID := rs.Primary.Attributes["space_id"] + if spaceID == "" { + return fmt.Errorf("no space_id is set") + } + + _, err := client.ContentTypes.Get(spaceID, rs.Primary.ID) + var notFoundError contentful.NotFoundError + if errors.As(err, ¬FoundError) { + return nil + } + + return fmt.Errorf("content type still exists with id: %s", rs.Primary.ID) + } + + return nil +} + +func testContentType(identifier string, spaceId string) string { + return utils.HCLTemplate(` + resource "contentful_contenttype" "{{ .identifier }}" { + space_id = "{{ .spaceId }}" + name = "tf_test1" + description = "Terraform Acc Test Content Type description change" + display_field = "field1" + fields = [{ + id = "field1" + name = "Field 1 name change" + required = true + type = "Text" + }, { + id = "field3" + name = "Field 3 new field" + required = true + type = "Integer" + }] +}`, map[string]any{ + "identifier": identifier, + "spaceId": spaceId, + }) +} + +func testContentTypeUpdate(identifier string, spaceId string) string { + return utils.HCLTemplate(` + resource "contentful_contenttype" "{{ .identifier }}" { + space_id = "{{ .spaceId }}" + name = "tf_test1" + description = "Terraform Acc Test Content Type description change" + display_field = "field1" +manage_field_controls = true + fields = [{ + id = "field1" + name = "Field 1 name change" + required = true + type = "Text" + }, { + id = "field3" + name = "Field 3 new field" + required = true + type = "Integer" + control = { + widget_id = "numberEditor" + widget_namespace = "builtin" + } + }] +}`, map[string]any{ + "identifier": identifier, + "spaceId": spaceId, + }) +} + +func testContentTypeLinkConfig(identifier string, spaceId string, linkIdentifier string) string { + return utils.HCLTemplate(`resource "contentful_contenttype" "{{ .identifier }}" { + space_id = "{{ .spaceId }}" + name = "tf_test1" + description = "Terraform Acc Test Content Type description change" + display_field = "field1" +manage_field_controls = true + fields = [{ + id = "field1" + name = "Field 1 name change" + required = true + type = "Text" + }, { + id = "field3" + name = "Field 3 new field" + required = true + type = "Integer" + control = { + widget_id = "numberEditor" + widget_namespace = "builtin" + } + }] +} + +resource "contentful_contenttype" "{{ .linkIdentifier }}" { + space_id = "{{ .spaceId }}" + name = "tf_linked" + description = "Terraform Acc Test Content Type with links" + display_field = "asset_field" + fields =[{ + id = "asset_field" + name = "Asset Field" + type = "Array" + items = { + type = "Link" + link_type = "Asset" + } + required = true + },{ + id = "entry_link_field" + name = "Entry Link Field" + type = "Link" + link_type = "Entry" + validations = [{ + link_content_type = [contentful_contenttype.{{ .identifier }}.id ] + }] + }] +} +`, map[string]any{ + "identifier": identifier, + "linkIdentifier": linkIdentifier, + "spaceId": spaceId, + }) +} diff --git a/internal/utils/container.go b/internal/utils/container.go new file mode 100644 index 0000000..25b28b4 --- /dev/null +++ b/internal/utils/container.go @@ -0,0 +1,7 @@ +package utils + +import "github.com/labd/contentful-go" + +type ProviderData struct { + Client *contentful.Client +} diff --git a/internal/utils/fields.go b/internal/utils/fields.go new file mode 100644 index 0000000..412f4a3 --- /dev/null +++ b/internal/utils/fields.go @@ -0,0 +1,13 @@ +package utils + +import ( + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +func FromOptionalString(value string) basetypes.StringValue { + if value == "" { + return types.StringNull() + } + return types.StringValue(value) +} diff --git a/internal/utils/hcl.go b/internal/utils/hcl.go new file mode 100644 index 0000000..5f8f9e1 --- /dev/null +++ b/internal/utils/hcl.go @@ -0,0 +1,16 @@ +package utils + +import ( + "bytes" + "text/template" +) + +func HCLTemplate(data string, params map[string]any) string { + var out bytes.Buffer + tmpl := template.Must(template.New("hcl").Parse(data)) + err := tmpl.Execute(&out, params) + if err != nil { + panic(err) + } + return out.String() +} diff --git a/main.go b/main.go index c9e17ff..5434f7f 100644 --- a/main.go +++ b/main.go @@ -1,9 +1,17 @@ package main import ( - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/hashicorp/terraform-plugin-sdk/v2/plugin" + "context" + "flag" + "fmt" + "github.com/hashicorp/terraform-plugin-framework/providerserver" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" + "github.com/hashicorp/terraform-plugin-go/tfprotov6/tf6server" + "github.com/hashicorp/terraform-plugin-mux/tf5to6server" + "github.com/hashicorp/terraform-plugin-mux/tf6muxserver" "github.com/labd/terraform-provider-contentful/contentful" + "github.com/labd/terraform-provider-contentful/internal/provider" + "log" ) // Run "go generate" to format example terraform files and generate the docs for the registry/website @@ -17,10 +25,57 @@ import ( // //go:generate go run github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs +var ( + // these will be set by the goreleaser configuration + // to appropriate values for the compiled binary + version string = "dev" + commit string = "snapshot" +) + func main() { - plugin.Serve(&plugin.ServeOpts{ - ProviderFunc: func() *schema.Provider { - return contentful.Provider() + + debugFlag := flag.Bool("debug", false, "Start provider in debug mode.") + flag.Parse() + + fullVersion := fmt.Sprintf("%s (%s)", version, commit) + + sdkProvider := contentful.Provider() + + ctx := context.Background() + + upgradedSdkProvider, err := tf5to6server.UpgradeServer( + ctx, + sdkProvider().GRPCProvider, + ) + + if err != nil { + log.Fatal(err) + } + + providers := []func() tfprotov6.ProviderServer{ + providerserver.NewProtocol6(provider.New(fullVersion, *debugFlag)), + func() tfprotov6.ProviderServer { + return upgradedSdkProvider }, - }) + } + + muxServer, err := tf6muxserver.NewMuxServer(ctx, providers...) + + if err != nil { + log.Fatal(err) + } + + var serveOpts []tf6server.ServeOpt + if *debugFlag { + serveOpts = append(serveOpts, tf6server.WithManagedDebug()) + } + + err = tf6server.Serve( + "registry.terraform.io/flaconi/contentful", + muxServer.ProviderServer, + serveOpts..., + ) + if err != nil { + log.Fatal(err) + } } From ea53e4ac81a6430a8ad77489110dd5d9ed96681c Mon Sep 17 00:00:00 2001 From: Engerim Date: Mon, 6 Nov 2023 10:11:10 +0000 Subject: [PATCH 153/192] Release v1.0.0 --- .changes/unreleased/Changed-20231106-090931.yaml | 3 --- .changes/v1.0.0.md | 3 +++ CHANGELOG.md | 4 ++++ 3 files changed, 7 insertions(+), 3 deletions(-) delete mode 100644 .changes/unreleased/Changed-20231106-090931.yaml create mode 100644 .changes/v1.0.0.md diff --git a/.changes/unreleased/Changed-20231106-090931.yaml b/.changes/unreleased/Changed-20231106-090931.yaml deleted file mode 100644 index 49cd211..0000000 --- a/.changes/unreleased/Changed-20231106-090931.yaml +++ /dev/null @@ -1,3 +0,0 @@ -kind: Changed -body: Extended ContentType to support enviroments, more validations, locales in environments -time: 2023-11-06T09:09:31.737754+01:00 diff --git a/.changes/v1.0.0.md b/.changes/v1.0.0.md new file mode 100644 index 0000000..83ce37a --- /dev/null +++ b/.changes/v1.0.0.md @@ -0,0 +1,3 @@ +## v1.0.0 - 2023-11-06 +### Changed +* Extended ContentType to support enviroments, more validations, locales in environments diff --git a/CHANGELOG.md b/CHANGELOG.md index 3dd2bf2..0c27d88 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), and is generated by [Changie](https://github.com/miniscruff/changie). +## v1.0.0 - 2023-11-06 +### Changed +* Extended ContentType to support enviroments, more validations, locales in environments + ## v0.5.2 - 2023-10-25 ### Fixed * use action correct From c52bcffec15c2085e07a2f26158a77bbc595dc7f Mon Sep 17 00:00:00 2001 From: Alexander Miehe Date: Mon, 6 Nov 2023 17:11:35 +0100 Subject: [PATCH 154/192] PLT-684 - Allow dedicated content type id --- .../contentful_contenttype/resource.tf | 16 ++++----- internal/resources/contenttype/model.go | 4 +++ internal/resources/contenttype/resource.go | 2 ++ .../resources/contenttype/resource_test.go | 34 +++++++++++++++++++ 4 files changed, 47 insertions(+), 9 deletions(-) diff --git a/examples/resources/contentful_contenttype/resource.tf b/examples/resources/contentful_contenttype/resource.tf index f3c0604..983f99d 100644 --- a/examples/resources/contentful_contenttype/resource.tf +++ b/examples/resources/contentful_contenttype/resource.tf @@ -3,28 +3,26 @@ resource "contentful_contenttype" "example_contenttype" { name = "tf_linked" description = "content type description" display_field = "asset_field" - field { + fields =[{ id = "asset_field" name = "Asset Field" type = "Array" - items { + items = { type = "Link" link_type = "Asset" } required = true - } - field { + }, { id = "entry_link_field" name = "Entry Link Field" type = "Link" link_type = "Entry" - validations = [ - jsonencode({ - linkContentType = [ + validations = [{ + link_content_type = [ contentful_contenttype.some_other_content_type.id ] - }) + } ] required = false - } + }] } \ No newline at end of file diff --git a/internal/resources/contenttype/model.go b/internal/resources/contenttype/model.go index b3f95f9..6557e61 100644 --- a/internal/resources/contenttype/model.go +++ b/internal/resources/contenttype/model.go @@ -492,6 +492,10 @@ func (c *ContentType) Draft() (*contentful.ContentType, error) { Fields: fields, } + if !c.ID.IsUnknown() || !c.ID.IsNull() { + contentfulType.Sys = &contentful.Sys{ID: c.ID.ValueString()} + } + if !c.Description.IsNull() && !c.Description.IsUnknown() { contentfulType.Description = c.Description.ValueStringPointer() } diff --git a/internal/resources/contenttype/resource.go b/internal/resources/contenttype/resource.go index 57f0189..e50c0a2 100644 --- a/internal/resources/contenttype/resource.go +++ b/internal/resources/contenttype/resource.go @@ -136,10 +136,12 @@ func (e *contentTypeResource) Schema(ctx context.Context, request resource.Schem Description: "Todo for explaining contenttype", Attributes: map[string]schema.Attribute{ "id": schema.StringAttribute{ + Optional: true, Computed: true, Description: "content type id", PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + stringplanmodifier.RequiresReplace(), }, }, "version": schema.Int64Attribute{ diff --git a/internal/resources/contenttype/resource_test.go b/internal/resources/contenttype/resource_test.go index 5b0fc63..65c4bcb 100644 --- a/internal/resources/contenttype/resource_test.go +++ b/internal/resources/contenttype/resource_test.go @@ -30,6 +30,7 @@ func TestContentTypeResource_Create(t *testing.T) { Config: testContentType("acctest_content_type", os.Getenv("CONTENTFUL_SPACE_ID")), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(resourceName, "name", "tf_test1"), + resource.TestCheckResourceAttr(resourceName, "id", "tf_test1"), resource.TestCheckResourceAttr(resourceName, "version", "2"), resource.TestCheckResourceAttr(resourceName, "version_controls", "0"), //todo check in contentful directly if the type looks like this @@ -51,6 +52,14 @@ func TestContentTypeResource_Create(t *testing.T) { //todo check in contentful directly if the type looks like this ), }, + { + Config: testContentTypeWithId("acctest_content_type", os.Getenv("CONTENTFUL_SPACE_ID")), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "name", "tf_test1"), + resource.TestCheckResourceAttr(resourceName, "id", "tf_test2"), + //todo check in contentful directly if the type looks like this + ), + }, }, }) } @@ -104,6 +113,31 @@ func testContentType(identifier string, spaceId string) string { }) } +func testContentTypeWithId(identifier string, spaceId string) string { + return utils.HCLTemplate(` + resource "contentful_contenttype" "{{ .identifier }}" { + space_id = "{{ .spaceId }}" + id = "tf_test2" + name = "tf_test1" + description = "Terraform Acc Test Content Type description change" + display_field = "field1" + fields = [{ + id = "field1" + name = "Field 1 name change" + required = true + type = "Text" + }, { + id = "field3" + name = "Field 3 new field" + required = true + type = "Integer" + }] +}`, map[string]any{ + "identifier": identifier, + "spaceId": spaceId, + }) +} + func testContentTypeUpdate(identifier string, spaceId string) string { return utils.HCLTemplate(` resource "contentful_contenttype" "{{ .identifier }}" { From b3652a7edf581b04c30feb33cabd77b12bf8ff66 Mon Sep 17 00:00:00 2001 From: Alexander Miehe Date: Wed, 8 Nov 2023 10:59:04 +0100 Subject: [PATCH 155/192] PLT-684 - Improve control settings (#11) * improve control settings * reduced amount of calls to contentful --- .../unreleased/Added-20231108-103604.yaml | 4 + go.mod | 2 +- go.sum | 4 +- .../int64allowedwhensetvalidator.go | 101 ++++++++++++++++++ internal/resources/contenttype/model.go | 82 ++++++-------- internal/resources/contenttype/resource.go | 94 +++++++++------- .../resources/contenttype/resource_test.go | 8 ++ 7 files changed, 204 insertions(+), 91 deletions(-) create mode 100644 .changes/unreleased/Added-20231108-103604.yaml create mode 100644 internal/customvalidator/int64allowedwhensetvalidator.go diff --git a/.changes/unreleased/Added-20231108-103604.yaml b/.changes/unreleased/Added-20231108-103604.yaml new file mode 100644 index 0000000..ef12955 --- /dev/null +++ b/.changes/unreleased/Added-20231108-103604.yaml @@ -0,0 +1,4 @@ +kind: Added +body: Added support for bulk_editing and tracking_field_id in settings; removed call + to get contentful environment +time: 2023-11-08T10:36:04.352414+01:00 diff --git a/go.mod b/go.mod index a2d55b2..84ced70 100644 --- a/go.mod +++ b/go.mod @@ -80,4 +80,4 @@ require ( moul.io/http2curl v1.0.1-0.20190925090545-5cd742060b0e // indirect ) -replace github.com/labd/contentful-go v0.5.3 => github.com/flaconi/contentful-go v0.5.3-0.20231103124131-f3613df0a465 +replace github.com/labd/contentful-go v0.5.3 => github.com/flaconi/contentful-go v0.5.3-0.20231108092912-20ae1a342984 diff --git a/go.sum b/go.sum index 4a91863..e2d4c21 100644 --- a/go.sum +++ b/go.sum @@ -41,8 +41,8 @@ github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5Kwzbycv github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= -github.com/flaconi/contentful-go v0.5.3-0.20231103124131-f3613df0a465 h1:GzhBeGqqrF+P63Ijps+lfy2Wzui8Y4t2r07j7zGtDcQ= -github.com/flaconi/contentful-go v0.5.3-0.20231103124131-f3613df0a465/go.mod h1:ciVUTFqeUtSSNjuEQnYLqbXvAlPu/aiPU4CsUc6Ug80= +github.com/flaconi/contentful-go v0.5.3-0.20231108092912-20ae1a342984 h1:tUFXR7L16W2YO710oodGODQFoiwJkuVXQEa9lbPj57g= +github.com/flaconi/contentful-go v0.5.3-0.20231108092912-20ae1a342984/go.mod h1:ciVUTFqeUtSSNjuEQnYLqbXvAlPu/aiPU4CsUc6Ug80= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= diff --git a/internal/customvalidator/int64allowedwhensetvalidator.go b/internal/customvalidator/int64allowedwhensetvalidator.go new file mode 100644 index 0000000..0e44d0e --- /dev/null +++ b/internal/customvalidator/int64allowedwhensetvalidator.go @@ -0,0 +1,101 @@ +package customvalidator + +import ( + "context" + "fmt" + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +var _ validator.Int64 = &int64AllowedWhenSetValidator{} + +type int64AllowedWhenSetValidator struct { + expression path.Expression + widgetType string +} + +func (i int64AllowedWhenSetValidator) Description(_ context.Context) string { + return fmt.Sprintf("Can only be configured for widget.id of type %s", i.widgetType) +} + +func (i int64AllowedWhenSetValidator) MarkdownDescription(ctx context.Context) string { + return i.Description(ctx) +} + +func (i int64AllowedWhenSetValidator) ValidateInt64(ctx context.Context, request validator.Int64Request, response *validator.Int64Response) { + // If the current attribute configuration is null or unknown, there + // cannot be any value comparisons, so exit early without error. + if request.ConfigValue.IsNull() || request.ConfigValue.IsUnknown() { + return + } + + // Combine the given path expressions with the current attribute path + // expression. This call automatically handles relative and absolute + // expressions. + expression := request.PathExpression.Merge(i.expression) + + // Find paths matching the expression in the configuration data. + matchedPaths, diags := request.Config.PathMatches(ctx, expression) + + response.Diagnostics.Append(diags...) + + // Collect all errors + if diags.HasError() { + return + } + + for _, matchedPath := range matchedPaths { + var matchedPathValue attr.Value + + diags = request.Config.GetAttribute(ctx, matchedPath, &matchedPathValue) + + response.Diagnostics.Append(diags...) + + // Collect all errors + if diags.HasError() { + continue + } + + // If the matched path value is null or unknown, we cannot compare + // values, so continue to other matched paths. + if matchedPathValue.IsNull() || matchedPathValue.IsUnknown() { + continue + } + + // Now that we know the matched path value is not null or unknown, + // it is safe to attempt converting it to the intended attr.Value + // implementation, in this case a types.Int64 value. + var matchedPathConfig types.String + + diags = tfsdk.ValueAs(ctx, matchedPathValue, &matchedPathConfig) + + response.Diagnostics.Append(diags...) + + // If the matched path value was not able to be converted from + // attr.Value to the intended types.Int64 implementation, it most + // likely means that the path expression was not pointing at a + // types.Int64Type attribute. Collect the error and continue to + // other matched paths. + if diags.HasError() { + continue + } + + if matchedPathConfig.ValueString() != i.widgetType { + response.Diagnostics.AddAttributeError( + request.Path, + "Invalid Attribute Value", + fmt.Sprintf("This value can only be set if the widget_id is \"%s\" but it is \"%s\". Path: %s", i.widgetType, matchedPathConfig.ValueString(), request.Path.String()), + ) + } + } +} + +func Int64AllowedWhenSetValidator(expression path.Expression, widgetType string) validator.Int64 { + return int64AllowedWhenSetValidator{ + expression: expression, + widgetType: widgetType, + } +} diff --git a/internal/resources/contenttype/model.go b/internal/resources/contenttype/model.go index 6557e61..41150e9 100644 --- a/internal/resources/contenttype/model.go +++ b/internal/resources/contenttype/model.go @@ -1,7 +1,6 @@ package contenttype import ( - "errors" "fmt" "github.com/elliotchance/pie/v2" "github.com/hashicorp/terraform-plugin-framework/attr" @@ -268,7 +267,7 @@ func getTypeOfMap(mapValues map[string]any) (*string, error) { t := "bool" return &t, nil default: - return nil, errors.New(fmt.Sprintf("The default type %T is not supported by the provider", c)) + return nil, fmt.Errorf("The default type %T is not supported by the provider", c) } } @@ -355,9 +354,6 @@ func (f *Field) Import(n *contentful.Field, c []contentful.Controls) error { settings.Import(c[idx].Settings) } - if val, ok := c[idx].Settings["helpText"]; ok { - settings.HelpText = types.StringValue(val) - } f.Control = &Control{ WidgetId: types.StringPointerValue(c[idx].WidgetID), @@ -370,59 +366,41 @@ func (f *Field) Import(n *contentful.Field, c []contentful.Controls) error { } type Settings struct { - HelpText types.String `tfsdk:"help_text"` - TrueLabel types.String `tfsdk:"true_label"` - FalseLabel types.String `tfsdk:"false_label"` - Stars types.String `tfsdk:"stars"` - Format types.String `tfsdk:"format"` - TimeFormat types.String `tfsdk:"ampm"` + HelpText types.String `tfsdk:"help_text"` + TrueLabel types.String `tfsdk:"true_label"` + FalseLabel types.String `tfsdk:"false_label"` + Stars types.Int64 `tfsdk:"stars"` + Format types.String `tfsdk:"format"` + TimeFormat types.String `tfsdk:"ampm"` + BulkEditing types.Bool `tfsdk:"bulk_editing"` + TrackingFieldId types.String `tfsdk:"tracking_field_id"` } -func (s *Settings) Import(settings map[string]string) { - if val, ok := settings["helpText"]; ok { - s.HelpText = types.StringValue(val) - } - - if val, ok := settings["trueLabel"]; ok { - s.TrueLabel = types.StringValue(val) - } - - if val, ok := settings["falseLabel"]; ok { - s.FalseLabel = types.StringValue(val) - } - - if val, ok := settings["stars"]; ok { - s.Stars = types.StringValue(val) - } - - if val, ok := settings["format"]; ok { - s.Format = types.StringValue(val) - } - - if val, ok := settings["ampm"]; ok { - s.TimeFormat = types.StringValue(val) - } +func (s *Settings) Import(settings *contentful.Settings) { + s.HelpText = types.StringPointerValue(settings.HelpText) + s.TrueLabel = types.StringPointerValue(settings.TrueLabel) + s.FalseLabel = types.StringPointerValue(settings.FalseLabel) + s.Stars = types.Int64PointerValue(settings.Stars) + s.Format = types.StringPointerValue(settings.Format) + s.TimeFormat = types.StringPointerValue(settings.AMPM) + s.BulkEditing = types.BoolPointerValue(settings.BulkEditing) + s.TrackingFieldId = types.StringPointerValue(settings.TrackingFieldId) } -func (s *Settings) Draft() map[string]string { - settings := make(map[string]string) - - addValue(s.HelpText, "helpText", settings) - addValue(s.Format, "format", settings) - addValue(s.Stars, "stars", settings) - addValue(s.FalseLabel, "falseLabel", settings) - addValue(s.TrueLabel, "trueLabel", settings) - addValue(s.TimeFormat, "ampm", settings) - +func (s *Settings) Draft() *contentful.Settings { + settings := &contentful.Settings{} + + settings.HelpText = s.HelpText.ValueStringPointer() + settings.TrueLabel = s.TrueLabel.ValueStringPointer() + settings.FalseLabel = s.FalseLabel.ValueStringPointer() + settings.Stars = s.Stars.ValueInt64Pointer() + settings.Format = s.Format.ValueStringPointer() + settings.AMPM = s.TimeFormat.ValueStringPointer() + settings.BulkEditing = s.BulkEditing.ValueBoolPointer() + settings.TrackingFieldId = s.TrackingFieldId.ValueStringPointer() return settings } -func addValue(val types.String, key string, settings map[string]string) { - if !val.IsUnknown() && !val.IsNull() { - settings[key] = val.ValueString() - } -} - type Items struct { Type types.String `tfsdk:"type"` LinkType types.String `tfsdk:"link_type"` @@ -773,5 +751,5 @@ func getValidation(cfVal contentful.FieldValidation) (*Validation, error) { }, nil } - return nil, errors.New(fmt.Sprintf("Unsupported validation used, %s. Please implement", reflect.TypeOf(cfVal).String())) + return nil, fmt.Errorf("Unsupported validation used, %s. Please implement", reflect.TypeOf(cfVal).String()) } diff --git a/internal/resources/contenttype/resource.go b/internal/resources/contenttype/resource.go index e50c0a2..3ba86f2 100644 --- a/internal/resources/contenttype/resource.go +++ b/internal/resources/contenttype/resource.go @@ -25,8 +25,10 @@ import ( "strings" ) +type key int + const ( - OnlyControlVersion = "onlyControlVersion" + OnlyControlVersion key = iota ) // Ensure the implementation satisfies the expected interfaces. @@ -132,6 +134,8 @@ func (e *contentTypeResource) Schema(ctx context.Context, request resource.Schem }, } + widgetIdPath := path.MatchRelative().AtParent().AtParent().AtName("widget_id") + response.Schema = schema.Schema{ Description: "Todo for explaining contenttype", Attributes: map[string]schema.Attribute{ @@ -285,33 +289,43 @@ func (e *contentTypeResource) Schema(ctx context.Context, request resource.Schem "true_label": schema.StringAttribute{ Optional: true, Validators: []validator.String{ - customvalidator.StringAllowedWhenSetValidator(path.MatchRelative().AtParent().AtParent().AtName("widget_id"), "boolean"), + customvalidator.StringAllowedWhenSetValidator(widgetIdPath, "boolean"), }, }, "false_label": schema.StringAttribute{ Optional: true, Validators: []validator.String{ - customvalidator.StringAllowedWhenSetValidator(path.MatchRelative().AtParent().AtParent().AtName("widget_id"), "boolean"), + customvalidator.StringAllowedWhenSetValidator(widgetIdPath, "boolean"), }, }, - "stars": schema.StringAttribute{ + "stars": schema.Int64Attribute{ Optional: true, - Validators: []validator.String{ - customvalidator.StringAllowedWhenSetValidator(path.MatchRelative().AtParent().AtParent().AtName("widget_id"), "rating"), + Validators: []validator.Int64{ + customvalidator.Int64AllowedWhenSetValidator(path.MatchRelative().AtParent().AtParent().AtName("widget_id"), "rating"), }, }, "format": schema.StringAttribute{ Optional: true, Validators: []validator.String{ stringvalidator.OneOf("dateonly", "time", "timeZ"), - customvalidator.StringAllowedWhenSetValidator(path.MatchRelative().AtParent().AtParent().AtName("widget_id"), "datepicker"), + customvalidator.StringAllowedWhenSetValidator(widgetIdPath, "datepicker"), }, }, "ampm": schema.StringAttribute{ Optional: true, Validators: []validator.String{ stringvalidator.OneOf("12", "24"), - customvalidator.StringAllowedWhenSetValidator(path.MatchRelative().AtParent().AtParent().AtName("widget_id"), "datepicker"), + customvalidator.StringAllowedWhenSetValidator(widgetIdPath, "datepicker"), + }, + }, + /** (only for References, many) Select whether to enable Bulk Editing mode */ + "bulk_editing": schema.BoolAttribute{ + Optional: true, + }, + "tracking_field_id": schema.StringAttribute{ + Optional: true, + Validators: []validator.String{ + customvalidator.StringAllowedWhenSetValidator(widgetIdPath, "slugEditor"), }, }, }, @@ -365,12 +379,12 @@ func (e *contentTypeResource) Create(ctx context.Context, request resource.Creat } } else { - env, envErr := e.client.Environments.Get(plan.SpaceId.ValueString(), plan.Environment.ValueString()) - - if envErr != nil { - response.Diagnostics.AddError("Error creating contenttype", envErr.Error()) - return - } + env := &contentful.Environment{Sys: &contentful.Sys{ + ID: plan.Environment.ValueString(), + Space: &contentful.Space{ + Sys: &contentful.Sys{ID: plan.SpaceId.ValueString()}, + }, + }} if err = e.client.ContentTypes.UpsertWithEnv(env, draft); err != nil { response.Diagnostics.AddError("Error creating contenttype", err.Error()) @@ -600,17 +614,18 @@ func (e *contentTypeResource) doUpdate(plan *ContentType, draft *contentful.Cont } } else { - env, err := e.client.Environments.Get(plan.SpaceId.ValueString(), plan.Environment.ValueString()) - - if err != nil { - return err - } + env := &contentful.Environment{Sys: &contentful.Sys{ + ID: plan.Environment.ValueString(), + Space: &contentful.Space{ + Sys: &contentful.Sys{ID: plan.SpaceId.ValueString()}, + }, + }} - if err = e.client.ContentTypes.UpsertWithEnv(env, draft); err != nil { + if err := e.client.ContentTypes.UpsertWithEnv(env, draft); err != nil { return err } - if err = e.client.ContentTypes.ActivateWithEnv(env, draft); err != nil { + if err := e.client.ContentTypes.ActivateWithEnv(env, draft); err != nil { return err } } @@ -655,17 +670,18 @@ func (e *contentTypeResource) doDelete(data *ContentType, draft *contentful.Cont } } else { - env, err := e.client.Environments.Get(data.SpaceId.ValueString(), data.Environment.ValueString()) - - if err != nil { - return err - } + env := &contentful.Environment{Sys: &contentful.Sys{ + ID: data.Environment.ValueString(), + Space: &contentful.Space{ + Sys: &contentful.Sys{ID: data.SpaceId.ValueString()}, + }, + }} - if err = e.client.ContentTypes.DeactivateWithEnv(env, draft); err != nil { + if err := e.client.ContentTypes.DeactivateWithEnv(env, draft); err != nil { return err } - if err = e.client.ContentTypes.DeleteWithEnv(env, draft); err != nil { + if err := e.client.ContentTypes.DeleteWithEnv(env, draft); err != nil { return err } @@ -695,11 +711,14 @@ func (e *contentTypeResource) ImportState(ctx context.Context, request resource. func (e *contentTypeResource) getContentType(editor *ContentType) (*contentful.ContentType, error) { if !editor.Environment.IsUnknown() && !editor.Environment.IsNull() { - env, err := e.client.Environments.Get(editor.SpaceId.ValueString(), editor.Environment.ValueString()) - if err != nil { - return nil, err - } + env := &contentful.Environment{Sys: &contentful.Sys{ + ID: editor.Environment.ValueString(), + Space: &contentful.Space{ + Sys: &contentful.Sys{ID: editor.SpaceId.ValueString()}, + }, + }} + return e.client.ContentTypes.GetWithEnv(env, editor.ID.ValueString()) } else { return e.client.ContentTypes.Get(editor.SpaceId.ValueString(), editor.ID.ValueString()) @@ -708,11 +727,14 @@ func (e *contentTypeResource) getContentType(editor *ContentType) (*contentful.C func (e *contentTypeResource) getContentTypeControls(editor *ContentType) (*contentful.EditorInterface, error) { if !editor.Environment.IsUnknown() && !editor.Environment.IsNull() { - env, err := e.client.Environments.Get(editor.SpaceId.ValueString(), editor.Environment.ValueString()) - if err != nil { - return nil, err - } + env := &contentful.Environment{Sys: &contentful.Sys{ + ID: editor.Environment.ValueString(), + Space: &contentful.Space{ + Sys: &contentful.Sys{ID: editor.SpaceId.ValueString()}, + }, + }} + return e.client.EditorInterfaces.GetWithEnv(env, editor.ID.ValueString()) } else { return e.client.EditorInterfaces.Get(editor.SpaceId.ValueString(), editor.ID.ValueString()) diff --git a/internal/resources/contenttype/resource_test.go b/internal/resources/contenttype/resource_test.go index 65c4bcb..3381ab6 100644 --- a/internal/resources/contenttype/resource_test.go +++ b/internal/resources/contenttype/resource_test.go @@ -159,6 +159,10 @@ manage_field_controls = true control = { widget_id = "numberEditor" widget_namespace = "builtin" + settings = { + help_text = "blabla" + bulk_editing = true + } } }] }`, map[string]any{ @@ -187,6 +191,10 @@ manage_field_controls = true control = { widget_id = "numberEditor" widget_namespace = "builtin" + settings = { + help_text = "blabla" + bulk_editing = false + } } }] } From 20ea831be15add58edf328f1083148a08a7922ea Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 8 Nov 2023 11:01:00 +0100 Subject: [PATCH 156/192] Release v1.1.0 (#12) Co-authored-by: Engerim --- .changes/unreleased/Added-20231108-103604.yaml | 4 ---- .changes/v1.1.0.md | 3 +++ CHANGELOG.md | 4 ++++ 3 files changed, 7 insertions(+), 4 deletions(-) delete mode 100644 .changes/unreleased/Added-20231108-103604.yaml create mode 100644 .changes/v1.1.0.md diff --git a/.changes/unreleased/Added-20231108-103604.yaml b/.changes/unreleased/Added-20231108-103604.yaml deleted file mode 100644 index ef12955..0000000 --- a/.changes/unreleased/Added-20231108-103604.yaml +++ /dev/null @@ -1,4 +0,0 @@ -kind: Added -body: Added support for bulk_editing and tracking_field_id in settings; removed call - to get contentful environment -time: 2023-11-08T10:36:04.352414+01:00 diff --git a/.changes/v1.1.0.md b/.changes/v1.1.0.md new file mode 100644 index 0000000..7cca132 --- /dev/null +++ b/.changes/v1.1.0.md @@ -0,0 +1,3 @@ +## v1.1.0 - 2023-11-08 +### Added +* Added support for bulk_editing and tracking_field_id in settings; removed call to get contentful environment diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c27d88..5b2f781 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), and is generated by [Changie](https://github.com/miniscruff/changie). +## v1.1.0 - 2023-11-08 +### Added +* Added support for bulk_editing and tracking_field_id in settings; removed call to get contentful environment + ## v1.0.0 - 2023-11-06 ### Changed * Extended ContentType to support enviroments, more validations, locales in environments From 49fa9fcd93e193b972c5f36cf3ae38dd6bc9b0da Mon Sep 17 00:00:00 2001 From: Alexander Miehe Date: Fri, 10 Nov 2023 15:03:48 +0100 Subject: [PATCH 157/192] PLT-0 - Fix issue that default values are not set in contentful (#13) --- .../unreleased/Fixed-20231110-150211.yaml | 3 ++ internal/resources/contenttype/model.go | 28 +++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 .changes/unreleased/Fixed-20231110-150211.yaml diff --git a/.changes/unreleased/Fixed-20231110-150211.yaml b/.changes/unreleased/Fixed-20231110-150211.yaml new file mode 100644 index 0000000..e7c3629 --- /dev/null +++ b/.changes/unreleased/Fixed-20231110-150211.yaml @@ -0,0 +1,3 @@ +kind: Fixed +body: Fixed issue that default values are not set +time: 2023-11-10T15:02:11.482718+01:00 diff --git a/internal/resources/contenttype/model.go b/internal/resources/contenttype/model.go index 41150e9..f14e0d5 100644 --- a/internal/resources/contenttype/model.go +++ b/internal/resources/contenttype/model.go @@ -44,6 +44,26 @@ type DefaultValue struct { String types.Map `tfsdk:"string"` } +func (d *DefaultValue) Draft() map[string]any { + var default_values = map[string]any{} + + if !d.String.IsNull() && !d.String.IsUnknown() { + + for k, v := range d.String.Elements() { + default_values[k] = v.(types.String).ValueString() + } + } + + if !d.Bool.IsNull() && !d.Bool.IsUnknown() { + + for k, v := range d.Bool.Elements() { + default_values[k] = v.(types.Bool).ValueBool() + } + } + + return default_values +} + type Control struct { WidgetId types.String `tfsdk:"widget_id"` WidgetNamespace types.String `tfsdk:"widget_namespace"` @@ -222,6 +242,10 @@ func (f *Field) Equal(n *contentful.Field) bool { } + if f.DefaultValue != nil && !reflect.DeepEqual(f.DefaultValue.Draft(), n.DefaultValue) { + return false + } + return true } @@ -254,6 +278,10 @@ func (f *Field) ToNative() (*contentful.Field, error) { contentfulField.Items = items } + if f.DefaultValue != nil { + contentfulField.DefaultValue = f.DefaultValue.Draft() + } + return contentfulField, nil } From c5fe00212311f60b910b34dc2c9a3a6d3433d69a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 10 Nov 2023 15:05:59 +0100 Subject: [PATCH 158/192] Release v1.1.1 (#14) Co-authored-by: Engerim --- .changes/unreleased/Fixed-20231110-150211.yaml | 3 --- .changes/v1.1.1.md | 3 +++ CHANGELOG.md | 4 ++++ 3 files changed, 7 insertions(+), 3 deletions(-) delete mode 100644 .changes/unreleased/Fixed-20231110-150211.yaml create mode 100644 .changes/v1.1.1.md diff --git a/.changes/unreleased/Fixed-20231110-150211.yaml b/.changes/unreleased/Fixed-20231110-150211.yaml deleted file mode 100644 index e7c3629..0000000 --- a/.changes/unreleased/Fixed-20231110-150211.yaml +++ /dev/null @@ -1,3 +0,0 @@ -kind: Fixed -body: Fixed issue that default values are not set -time: 2023-11-10T15:02:11.482718+01:00 diff --git a/.changes/v1.1.1.md b/.changes/v1.1.1.md new file mode 100644 index 0000000..1181aed --- /dev/null +++ b/.changes/v1.1.1.md @@ -0,0 +1,3 @@ +## v1.1.1 - 2023-11-10 +### Fixed +* Fixed issue that default values are not set diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b2f781..fe4bbaa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), and is generated by [Changie](https://github.com/miniscruff/changie). +## v1.1.1 - 2023-11-10 +### Fixed +* Fixed issue that default values are not set + ## v1.1.0 - 2023-11-08 ### Added * Added support for bulk_editing and tracking_field_id in settings; removed call to get contentful environment From 133b95d16833c08563c36744ca90e843f55525ab Mon Sep 17 00:00:00 2001 From: Alexander Miehe Date: Mon, 13 Nov 2023 12:38:49 +0100 Subject: [PATCH 159/192] PLT-0 - Prevent field type change (#15) --- .../unreleased/Added-20231113-104147.yaml | 3 ++ internal/custommodifier/booldefault.go | 4 +- internal/custommodifier/int64default.go | 4 +- .../custommodifier/stringchangeprohibited.go | 46 +++++++++++++++++++ internal/resources/contenttype/resource.go | 4 ++ 5 files changed, 57 insertions(+), 4 deletions(-) create mode 100644 .changes/unreleased/Added-20231113-104147.yaml create mode 100644 internal/custommodifier/stringchangeprohibited.go diff --git a/.changes/unreleased/Added-20231113-104147.yaml b/.changes/unreleased/Added-20231113-104147.yaml new file mode 100644 index 0000000..a2855ec --- /dev/null +++ b/.changes/unreleased/Added-20231113-104147.yaml @@ -0,0 +1,3 @@ +kind: Added +body: Prevent field type change with error +time: 2023-11-13T10:41:47.122868+01:00 diff --git a/internal/custommodifier/booldefault.go b/internal/custommodifier/booldefault.go index dd05fc3..25b0c23 100644 --- a/internal/custommodifier/booldefault.go +++ b/internal/custommodifier/booldefault.go @@ -22,8 +22,8 @@ func (m boolDefaultModifier) Description(_ context.Context) string { } // MarkdownDescription returns a markdown description of the plan modifier. -func (m boolDefaultModifier) MarkdownDescription(_ context.Context) string { - return fmt.Sprintf("If value is not configured, defaults to `%t`", m.Default) +func (m boolDefaultModifier) MarkdownDescription(ctx context.Context) string { + return m.Description(ctx) } func (m boolDefaultModifier) PlanModifyBool(_ context.Context, _ planmodifier.BoolRequest, resp *planmodifier.BoolResponse) { diff --git a/internal/custommodifier/int64default.go b/internal/custommodifier/int64default.go index 980f21a..1de7e23 100644 --- a/internal/custommodifier/int64default.go +++ b/internal/custommodifier/int64default.go @@ -22,8 +22,8 @@ func (m int64DefaultModifier) Description(_ context.Context) string { } // MarkdownDescription returns a markdown description of the plan modifier. -func (m int64DefaultModifier) MarkdownDescription(_ context.Context) string { - return fmt.Sprintf("If value is not configured, defaults to `%d`", m.Default) +func (m int64DefaultModifier) MarkdownDescription(ctx context.Context) string { + return m.Description(ctx) } func (m int64DefaultModifier) PlanModifyInt64(_ context.Context, _ planmodifier.Int64Request, resp *planmodifier.Int64Response) { diff --git a/internal/custommodifier/stringchangeprohibited.go b/internal/custommodifier/stringchangeprohibited.go new file mode 100644 index 0000000..dba601d --- /dev/null +++ b/internal/custommodifier/stringchangeprohibited.go @@ -0,0 +1,46 @@ +package custommodifier + +import ( + "context" + "fmt" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" +) + +// From https://developer.hashicorp.com/terraform/plugin/framework/resources/plan-modification#creating-attribute-plan-modifiers + +var _ planmodifier.String = stringChangeProhibited{} +var _ planmodifier.String = stringChangeProhibited{} + +type stringChangeProhibited struct { + Message string + Summary string +} + +func (s stringChangeProhibited) Description(_ context.Context) string { + return fmt.Sprint("If value is already configured, prevent any change") +} + +func (s stringChangeProhibited) MarkdownDescription(ctx context.Context) string { + return s.Description(ctx) +} + +func (s stringChangeProhibited) PlanModifyString(_ context.Context, request planmodifier.StringRequest, response *planmodifier.StringResponse) { + if request.StateValue.IsNull() { + return + } + + if !request.PlanValue.IsUnknown() && !request.PlanValue.Equal(request.StateValue) { + // Return an example warning diagnostic to practitioners. + response.Diagnostics.AddError( + s.Summary, + s.Message, + ) + } +} + +func StringChangeProhibited(summary string, detail string) planmodifier.String { + return stringChangeProhibited{ + Message: detail, + Summary: summary, + } +} diff --git a/internal/resources/contenttype/resource.go b/internal/resources/contenttype/resource.go index 3ba86f2..ee5f77b 100644 --- a/internal/resources/contenttype/resource.go +++ b/internal/resources/contenttype/resource.go @@ -201,6 +201,10 @@ func (e *contentTypeResource) Schema(ctx context.Context, request resource.Schem Validators: []validator.String{ stringvalidator.OneOf(contentfulTypes...), }, + PlanModifiers: []planmodifier.String{ + custommodifier.StringChangeProhibited("Content Type Field Type Change", "Changing a field type in contentful is not possible. Pls follow this faq: "+ + "https://www.contentful.com/faq/best-practices/#how-to-change-field-type"), + }, }, "link_type": schema.StringAttribute{ Optional: true, From 76b339d8ab14b4b31e5d354dc31cc8d902428082 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 13 Nov 2023 13:10:23 +0100 Subject: [PATCH 160/192] Release v1.2.0 (#16) Co-authored-by: Engerim --- .changes/unreleased/Added-20231113-104147.yaml | 3 --- .changes/v1.2.0.md | 3 +++ CHANGELOG.md | 4 ++++ 3 files changed, 7 insertions(+), 3 deletions(-) delete mode 100644 .changes/unreleased/Added-20231113-104147.yaml create mode 100644 .changes/v1.2.0.md diff --git a/.changes/unreleased/Added-20231113-104147.yaml b/.changes/unreleased/Added-20231113-104147.yaml deleted file mode 100644 index a2855ec..0000000 --- a/.changes/unreleased/Added-20231113-104147.yaml +++ /dev/null @@ -1,3 +0,0 @@ -kind: Added -body: Prevent field type change with error -time: 2023-11-13T10:41:47.122868+01:00 diff --git a/.changes/v1.2.0.md b/.changes/v1.2.0.md new file mode 100644 index 0000000..040dbca --- /dev/null +++ b/.changes/v1.2.0.md @@ -0,0 +1,3 @@ +## v1.2.0 - 2023-11-13 +### Added +* Prevent field type change with error diff --git a/CHANGELOG.md b/CHANGELOG.md index fe4bbaa..5ffa4f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), and is generated by [Changie](https://github.com/miniscruff/changie). +## v1.2.0 - 2023-11-13 +### Added +* Prevent field type change with error + ## v1.1.1 - 2023-11-10 ### Fixed * Fixed issue that default values are not set From ca4c9c1b72891b9a48ed90012ada6babd45ed22a Mon Sep 17 00:00:00 2001 From: Alexander Miehe Date: Tue, 14 Nov 2023 10:53:43 +0100 Subject: [PATCH 161/192] PLT-0 - Prevent field type change (#17) * fix the field type change validation to allow fields in the middle --- .../unreleased/Fixed-20231114-102528.yaml | 3 ++ .../fieldtypechangeprohibited.go | 54 +++++++++++++++++++ .../custommodifier/stringchangeprohibited.go | 46 ---------------- internal/resources/contenttype/resource.go | 7 ++- 4 files changed, 60 insertions(+), 50 deletions(-) create mode 100644 .changes/unreleased/Fixed-20231114-102528.yaml create mode 100644 internal/custommodifier/fieldtypechangeprohibited.go delete mode 100644 internal/custommodifier/stringchangeprohibited.go diff --git a/.changes/unreleased/Fixed-20231114-102528.yaml b/.changes/unreleased/Fixed-20231114-102528.yaml new file mode 100644 index 0000000..947cdc8 --- /dev/null +++ b/.changes/unreleased/Fixed-20231114-102528.yaml @@ -0,0 +1,3 @@ +kind: Fixed +body: Fixed field type validation to allow new fields in the middle +time: 2023-11-14T10:25:28.030573+01:00 diff --git a/internal/custommodifier/fieldtypechangeprohibited.go b/internal/custommodifier/fieldtypechangeprohibited.go new file mode 100644 index 0000000..bca0757 --- /dev/null +++ b/internal/custommodifier/fieldtypechangeprohibited.go @@ -0,0 +1,54 @@ +package custommodifier + +import ( + "context" + "fmt" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// From https://developer.hashicorp.com/terraform/plugin/framework/resources/plan-modification#creating-attribute-plan-modifiers + +var _ planmodifier.Object = fieldTypeChangeProhibited{} +var _ planmodifier.Object = fieldTypeChangeProhibited{} + +type fieldTypeChangeProhibited struct{} + +func (s fieldTypeChangeProhibited) Description(_ context.Context) string { + return fmt.Sprint("If value is already configured, prevent any change") +} + +func (s fieldTypeChangeProhibited) MarkdownDescription(ctx context.Context) string { + return s.Description(ctx) +} + +func (s fieldTypeChangeProhibited) PlanModifyObject(ctx context.Context, request planmodifier.ObjectRequest, response *planmodifier.ObjectResponse) { + if request.StateValue.IsNull() { + return + } + + var fieldsList basetypes.ListValue + + diags := request.State.GetAttribute(ctx, request.Path.ParentPath(), &fieldsList) + + response.Diagnostics.Append(diags...) + + for _, value := range fieldsList.Elements() { + + stateFields := value.(basetypes.ObjectValue).Attributes() + planFields := request.PlanValue.Attributes() + + if planFields["id"].Equal(stateFields["id"]) { + if !planFields["type"].Equal(stateFields["type"]) { + response.Diagnostics.AddError( + fmt.Sprintf("Content Type Field Type Change for Field %s", planFields["id"].String()), "Changing a field type in contentful is not possible. Pls follow this faq: "+ + "https://www.contentful.com/faq/best-practices/#how-to-change-field-type", + ) + } + } + } +} + +func FieldTypeChangeProhibited() planmodifier.Object { + return fieldTypeChangeProhibited{} +} diff --git a/internal/custommodifier/stringchangeprohibited.go b/internal/custommodifier/stringchangeprohibited.go deleted file mode 100644 index dba601d..0000000 --- a/internal/custommodifier/stringchangeprohibited.go +++ /dev/null @@ -1,46 +0,0 @@ -package custommodifier - -import ( - "context" - "fmt" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" -) - -// From https://developer.hashicorp.com/terraform/plugin/framework/resources/plan-modification#creating-attribute-plan-modifiers - -var _ planmodifier.String = stringChangeProhibited{} -var _ planmodifier.String = stringChangeProhibited{} - -type stringChangeProhibited struct { - Message string - Summary string -} - -func (s stringChangeProhibited) Description(_ context.Context) string { - return fmt.Sprint("If value is already configured, prevent any change") -} - -func (s stringChangeProhibited) MarkdownDescription(ctx context.Context) string { - return s.Description(ctx) -} - -func (s stringChangeProhibited) PlanModifyString(_ context.Context, request planmodifier.StringRequest, response *planmodifier.StringResponse) { - if request.StateValue.IsNull() { - return - } - - if !request.PlanValue.IsUnknown() && !request.PlanValue.Equal(request.StateValue) { - // Return an example warning diagnostic to practitioners. - response.Diagnostics.AddError( - s.Summary, - s.Message, - ) - } -} - -func StringChangeProhibited(summary string, detail string) planmodifier.String { - return stringChangeProhibited{ - Message: detail, - Summary: summary, - } -} diff --git a/internal/resources/contenttype/resource.go b/internal/resources/contenttype/resource.go index ee5f77b..fcbdf92 100644 --- a/internal/resources/contenttype/resource.go +++ b/internal/resources/contenttype/resource.go @@ -201,10 +201,6 @@ func (e *contentTypeResource) Schema(ctx context.Context, request resource.Schem Validators: []validator.String{ stringvalidator.OneOf(contentfulTypes...), }, - PlanModifiers: []planmodifier.String{ - custommodifier.StringChangeProhibited("Content Type Field Type Change", "Changing a field type in contentful is not possible. Pls follow this faq: "+ - "https://www.contentful.com/faq/best-practices/#how-to-change-field-type"), - }, }, "link_type": schema.StringAttribute{ Optional: true, @@ -341,6 +337,9 @@ func (e *contentTypeResource) Schema(ctx context.Context, request resource.Schem }, }, }, + PlanModifiers: []planmodifier.Object{ + custommodifier.FieldTypeChangeProhibited(), + }, }, }, }, From 6b42130233aef1713f452b944d90f33b45f03ede Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 14 Nov 2023 10:56:09 +0100 Subject: [PATCH 162/192] Release v1.2.1 (#18) Co-authored-by: Engerim --- .changes/unreleased/Fixed-20231114-102528.yaml | 3 --- .changes/v1.2.1.md | 3 +++ CHANGELOG.md | 4 ++++ 3 files changed, 7 insertions(+), 3 deletions(-) delete mode 100644 .changes/unreleased/Fixed-20231114-102528.yaml create mode 100644 .changes/v1.2.1.md diff --git a/.changes/unreleased/Fixed-20231114-102528.yaml b/.changes/unreleased/Fixed-20231114-102528.yaml deleted file mode 100644 index 947cdc8..0000000 --- a/.changes/unreleased/Fixed-20231114-102528.yaml +++ /dev/null @@ -1,3 +0,0 @@ -kind: Fixed -body: Fixed field type validation to allow new fields in the middle -time: 2023-11-14T10:25:28.030573+01:00 diff --git a/.changes/v1.2.1.md b/.changes/v1.2.1.md new file mode 100644 index 0000000..7be6808 --- /dev/null +++ b/.changes/v1.2.1.md @@ -0,0 +1,3 @@ +## v1.2.1 - 2023-11-14 +### Fixed +* Fixed field type validation to allow new fields in the middle diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ffa4f7..525e9cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), and is generated by [Changie](https://github.com/miniscruff/changie). +## v1.2.1 - 2023-11-14 +### Fixed +* Fixed field type validation to allow new fields in the middle + ## v1.2.0 - 2023-11-13 ### Added * Prevent field type change with error From 1c38f00a471ee32a8fd5354052cb2df29809830e Mon Sep 17 00:00:00 2001 From: Alexander Miehe Date: Wed, 29 Nov 2023 09:33:06 +0100 Subject: [PATCH 163/192] PLT-0 - update go releaser (#19) --- .github/workflows/release.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 913264e..1cc2042 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -24,10 +24,10 @@ jobs: passphrase: ${{ secrets.PASSPHRASE }} - name: Run GoReleaser - uses: goreleaser/goreleaser-action@v2 + uses: goreleaser/goreleaser-action@v5 with: version: latest - args: release --rm-dist + args: release --clean env: GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From f53b8b5b6e62d458899366123642d12018427eb6 Mon Sep 17 00:00:00 2001 From: Alexander Miehe Date: Fri, 8 Dec 2023 12:30:08 +0100 Subject: [PATCH 164/192] PLT-746 - Add support for apps (#20) * allow to config apps in terraform --- .../unreleased/Added-20231208-120207.yaml | 3 + go.mod | 35 +- go.sum | 76 ++-- .../attributeneedstobesetvalidator.go | 84 +++++ .../stringallowedwhensetvalidator.go | 2 +- .../whenothervalueexistlistvalidator.go | 76 ++++ internal/provider/provider.go | 5 +- internal/resources/app_definition/bundle.zip | Bin 0 -> 390 bytes internal/resources/app_definition/model.go | 192 ++++++++++ internal/resources/app_definition/resource.go | 331 ++++++++++++++++++ .../resources/app_definition/resource_test.go | 201 +++++++++++ internal/resources/contenttype/model.go | 23 +- internal/resources/contenttype/resource.go | 35 +- internal/utils/container.go | 3 +- internal/utils/fields.go | 19 + internal/utils/types.go | 28 ++ 16 files changed, 1017 insertions(+), 96 deletions(-) create mode 100644 .changes/unreleased/Added-20231208-120207.yaml create mode 100644 internal/customvalidator/attributeneedstobesetvalidator.go create mode 100644 internal/customvalidator/whenothervalueexistlistvalidator.go create mode 100644 internal/resources/app_definition/bundle.zip create mode 100644 internal/resources/app_definition/model.go create mode 100644 internal/resources/app_definition/resource.go create mode 100644 internal/resources/app_definition/resource_test.go create mode 100644 internal/utils/types.go diff --git a/.changes/unreleased/Added-20231208-120207.yaml b/.changes/unreleased/Added-20231208-120207.yaml new file mode 100644 index 0000000..e99ea12 --- /dev/null +++ b/.changes/unreleased/Added-20231208-120207.yaml @@ -0,0 +1,3 @@ +kind: Added +body: Add support app configuration in the organization +time: 2023-12-08T12:02:07.240628+01:00 diff --git a/go.mod b/go.mod index 84ced70..8fc5a86 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,9 @@ require ( github.com/hashicorp/terraform-plugin-framework v1.4.2 github.com/hashicorp/terraform-plugin-framework-validators v0.12.0 github.com/hashicorp/terraform-plugin-mux v0.12.0 + github.com/hashicorp/terraform-plugin-testing v1.6.0 github.com/labd/contentful-go v0.5.3 + github.com/stretchr/testify v1.8.4 ) require ( @@ -20,22 +22,25 @@ require ( github.com/armon/go-radix v1.0.0 // indirect github.com/bgentry/speakeasy v0.1.0 // indirect github.com/cloudflare/circl v1.3.3 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect github.com/google/uuid v1.3.1 // indirect - github.com/hashicorp/hc-install v0.6.0 // indirect + github.com/hashicorp/hc-install v0.6.1 // indirect github.com/hashicorp/terraform-plugin-log v0.9.0 // indirect - github.com/hashicorp/terraform-registry-address v0.2.2 // indirect + github.com/hashicorp/terraform-registry-address v0.2.3 // indirect github.com/hashicorp/terraform-svchost v0.1.1 // indirect github.com/huandu/xstrings v1.4.0 // indirect github.com/imdario/mergo v0.3.16 // indirect github.com/mitchellh/cli v1.1.5 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect github.com/posener/complete v1.2.3 // indirect github.com/russross/blackfriday v1.6.0 // indirect github.com/shopspring/decimal v1.3.1 // indirect github.com/spf13/cast v1.5.1 // indirect - github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect + github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230913181813-007df8e322eb // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) require ( @@ -49,15 +54,15 @@ require ( github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 // indirect github.com/hashicorp/go-hclog v1.5.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect - github.com/hashicorp/go-plugin v1.5.1 // indirect + github.com/hashicorp/go-plugin v1.5.2 // indirect github.com/hashicorp/go-uuid v1.0.3 // indirect github.com/hashicorp/go-version v1.6.0 // indirect - github.com/hashicorp/hcl/v2 v2.18.0 // indirect + github.com/hashicorp/hcl/v2 v2.19.1 // indirect github.com/hashicorp/logutils v1.0.0 // indirect github.com/hashicorp/terraform-exec v0.19.0 // indirect - github.com/hashicorp/terraform-json v0.17.1 // indirect - github.com/hashicorp/terraform-plugin-go v0.19.0 - github.com/hashicorp/terraform-plugin-sdk/v2 v2.29.0 + github.com/hashicorp/terraform-json v0.18.0 // indirect + github.com/hashicorp/terraform-plugin-go v0.19.1 + github.com/hashicorp/terraform-plugin-sdk/v2 v2.30.0 github.com/hashicorp/yamux v0.1.1 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.19 // indirect @@ -68,16 +73,16 @@ require ( github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/oklog/run v1.1.0 // indirect github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect - github.com/zclconf/go-cty v1.14.0 // indirect - golang.org/x/crypto v0.14.0 // indirect - golang.org/x/mod v0.12.0 // indirect + github.com/zclconf/go-cty v1.14.1 // indirect + golang.org/x/crypto v0.16.0 // indirect + golang.org/x/mod v0.13.0 // indirect golang.org/x/net v0.17.0 // indirect - golang.org/x/sys v0.13.0 // indirect - golang.org/x/text v0.13.0 // indirect + golang.org/x/sys v0.15.0 // indirect + golang.org/x/text v0.14.0 // indirect google.golang.org/appengine v1.6.8 // indirect - google.golang.org/grpc v1.58.1 // indirect + google.golang.org/grpc v1.59.0 // indirect google.golang.org/protobuf v1.31.0 // indirect moul.io/http2curl v1.0.1-0.20190925090545-5cd742060b0e // indirect ) -replace github.com/labd/contentful-go v0.5.3 => github.com/flaconi/contentful-go v0.5.3-0.20231108092912-20ae1a342984 +replace github.com/labd/contentful-go v0.5.3 => github.com/flaconi/contentful-go v0.5.3-0.20231208091000-136be0669443 diff --git a/go.sum b/go.sum index e2d4c21..639b2bf 100644 --- a/go.sum +++ b/go.sum @@ -30,6 +30,8 @@ github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs= github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= +github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= +github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= 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= @@ -41,16 +43,16 @@ github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5Kwzbycv github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= -github.com/flaconi/contentful-go v0.5.3-0.20231108092912-20ae1a342984 h1:tUFXR7L16W2YO710oodGODQFoiwJkuVXQEa9lbPj57g= -github.com/flaconi/contentful-go v0.5.3-0.20231108092912-20ae1a342984/go.mod h1:ciVUTFqeUtSSNjuEQnYLqbXvAlPu/aiPU4CsUc6Ug80= +github.com/flaconi/contentful-go v0.5.3-0.20231208091000-136be0669443 h1:Pk1gUs5HYHbjBmuUSEcj6g0RQrquBdehHAzIe/supqo= +github.com/flaconi/contentful-go v0.5.3-0.20231208091000-136be0669443/go.mod h1:ciVUTFqeUtSSNjuEQnYLqbXvAlPu/aiPU4CsUc6Ug80= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= -github.com/go-git/go-billy/v5 v5.4.1 h1:Uwp5tDRkPr+l/TnbHOQzp+tmJfLceOlbVucgpTz8ix4= -github.com/go-git/go-billy/v5 v5.4.1/go.mod h1:vjbugF6Fz7JIflbVpl1hJsGjSHNltrSw45YK/ukIvQg= -github.com/go-git/go-git/v5 v5.8.1 h1:Zo79E4p7TRk0xoRgMq0RShiTHGKcKI4+DI6BfJc/Q+A= -github.com/go-git/go-git/v5 v5.8.1/go.mod h1:FHFuoD6yGz5OSKEBK+aWN9Oah0q54Jxl0abmj6GnqAo= +github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU= +github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow= +github.com/go-git/go-git/v5 v5.9.0 h1:cD9SFA7sHVRdJ7AYck1ZaAa/yeuBvGPxwXDL8cxrObY= +github.com/go-git/go-git/v5 v5.9.0/go.mod h1:RKIqga24sWdMGZF+1Ekv9kylsDz6LzdTSI2s/OsZWE0= 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/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= @@ -83,39 +85,41 @@ github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVH github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/go-plugin v1.5.1 h1:oGm7cWBaYIp3lJpx1RUEfLWophprE2EV/KUeqBYo+6k= -github.com/hashicorp/go-plugin v1.5.1/go.mod h1:w1sAEES3g3PuV/RzUrgow20W2uErMly84hhD3um1WL4= +github.com/hashicorp/go-plugin v1.5.2 h1:aWv8eimFqWlsEiMrYZdPYl+FdHaBJSN4AWwGWfT1G2Y= +github.com/hashicorp/go-plugin v1.5.2/go.mod h1:w1sAEES3g3PuV/RzUrgow20W2uErMly84hhD3um1WL4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/hc-install v0.6.0 h1:fDHnU7JNFNSQebVKYhHZ0va1bC6SrPQ8fpebsvNr2w4= -github.com/hashicorp/hc-install v0.6.0/go.mod h1:10I912u3nntx9Umo1VAeYPUUuehk0aRQJYpMwbX5wQA= -github.com/hashicorp/hcl/v2 v2.18.0 h1:wYnG7Lt31t2zYkcquwgKo6MWXzRUDIeIVU5naZwHLl8= -github.com/hashicorp/hcl/v2 v2.18.0/go.mod h1:ThLC89FV4p9MPW804KVbe/cEXoQ8NZEh+JtMeeGErHE= +github.com/hashicorp/hc-install v0.6.1 h1:IGxShH7AVhPaSuSJpKtVi/EFORNjO+OYVJJrAtGG2mY= +github.com/hashicorp/hc-install v0.6.1/go.mod h1:0fW3jpg+wraYSnFDJ6Rlie3RvLf1bIqVIkzoon4KoVE= +github.com/hashicorp/hcl/v2 v2.19.1 h1://i05Jqznmb2EXqa39Nsvyan2o5XyMowW5fnCKW5RPI= +github.com/hashicorp/hcl/v2 v2.19.1/go.mod h1:ThLC89FV4p9MPW804KVbe/cEXoQ8NZEh+JtMeeGErHE= 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/terraform-exec v0.19.0 h1:FpqZ6n50Tk95mItTSS9BjeOVUb4eg81SpgVtZNNtFSM= github.com/hashicorp/terraform-exec v0.19.0/go.mod h1:tbxUpe3JKruE9Cuf65mycSIT8KiNPZ0FkuTE3H4urQg= -github.com/hashicorp/terraform-json v0.17.1 h1:eMfvh/uWggKmY7Pmb3T85u86E2EQg6EQHgyRwf3RkyA= -github.com/hashicorp/terraform-json v0.17.1/go.mod h1:Huy6zt6euxaY9knPAFKjUITn8QxUFIe9VuSzb4zn/0o= +github.com/hashicorp/terraform-json v0.18.0 h1:pCjgJEqqDESv4y0Tzdqfxr/edOIGkjs8keY42xfNBwU= +github.com/hashicorp/terraform-json v0.18.0/go.mod h1:qdeBs11ovMzo5puhrRibdD6d2Dq6TyE/28JiU4tIQxk= github.com/hashicorp/terraform-plugin-docs v0.16.0 h1:UmxFr3AScl6Wged84jndJIfFccGyBZn52KtMNsS12dI= github.com/hashicorp/terraform-plugin-docs v0.16.0/go.mod h1:M3ZrlKBJAbPMtNOPwHicGi1c+hZUh7/g0ifT/z7TVfA= github.com/hashicorp/terraform-plugin-framework v1.4.2 h1:P7a7VP1GZbjc4rv921Xy5OckzhoiO3ig6SGxwelD2sI= github.com/hashicorp/terraform-plugin-framework v1.4.2/go.mod h1:GWl3InPFZi2wVQmdVnINPKys09s9mLmTZr95/ngLnbY= github.com/hashicorp/terraform-plugin-framework-validators v0.12.0 h1:HOjBuMbOEzl7snOdOoUfE2Jgeto6JOjLVQ39Ls2nksc= github.com/hashicorp/terraform-plugin-framework-validators v0.12.0/go.mod h1:jfHGE/gzjxYz6XoUwi/aYiiKrJDeutQNUtGQXkaHklg= -github.com/hashicorp/terraform-plugin-go v0.19.0 h1:BuZx/6Cp+lkmiG0cOBk6Zps0Cb2tmqQpDM3iAtnhDQU= -github.com/hashicorp/terraform-plugin-go v0.19.0/go.mod h1:EhRSkEPNoylLQntYsk5KrDHTZJh9HQoumZXbOGOXmec= +github.com/hashicorp/terraform-plugin-go v0.19.1 h1:lf/jTGTeELcz5IIbn/94mJdmnTjRYm6S6ct/JqCSr50= +github.com/hashicorp/terraform-plugin-go v0.19.1/go.mod h1:5NMIS+DXkfacX6o5HCpswda5yjkSYfKzn1Nfl9l+qRs= github.com/hashicorp/terraform-plugin-log v0.9.0 h1:i7hOA+vdAItN1/7UrfBqBwvYPQ9TFvymaRGZED3FCV0= github.com/hashicorp/terraform-plugin-log v0.9.0/go.mod h1:rKL8egZQ/eXSyDqzLUuwUYLVdlYeamldAHSxjUFADow= github.com/hashicorp/terraform-plugin-mux v0.12.0 h1:TJlmeslQ11WlQtIFAfth0vXx+gSNgvMEng2Rn9z3WZY= github.com/hashicorp/terraform-plugin-mux v0.12.0/go.mod h1:8MR0AgmV+Q03DIjyrAKxXyYlq2EUnYBQP8gxAAA0zeM= -github.com/hashicorp/terraform-plugin-sdk/v2 v2.29.0 h1:wcOKYwPI9IorAJEBLzgclh3xVolO7ZorYd6U1vnok14= -github.com/hashicorp/terraform-plugin-sdk/v2 v2.29.0/go.mod h1:qH/34G25Ugdj5FcM95cSoXzUgIbgfhVLXCcEcYaMwq8= -github.com/hashicorp/terraform-registry-address v0.2.2 h1:lPQBg403El8PPicg/qONZJDC6YlgCVbWDtNmmZKtBno= -github.com/hashicorp/terraform-registry-address v0.2.2/go.mod h1:LtwNbCihUoUZ3RYriyS2wF/lGPB6gF9ICLRtuDk7hSo= +github.com/hashicorp/terraform-plugin-sdk/v2 v2.30.0 h1:X7vB6vn5tON2b49ILa4W7mFAsndeqJ7bZFOGbVO+0Cc= +github.com/hashicorp/terraform-plugin-sdk/v2 v2.30.0/go.mod h1:ydFcxbdj6klCqYEPkPvdvFKiNGKZLUs+896ODUXCyao= +github.com/hashicorp/terraform-plugin-testing v1.6.0 h1:Wsnfh+7XSVRfwcr2jZYHsnLOnZl7UeaOBvsx6dl/608= +github.com/hashicorp/terraform-plugin-testing v1.6.0/go.mod h1:cJGG0/8j9XhHaJZRC+0sXFI4uzqQZ9Az4vh6C4GJpFE= +github.com/hashicorp/terraform-registry-address v0.2.3 h1:2TAiKJ1A3MAkZlH1YI/aTVcLZRu7JseiXNRHbOAyoTI= +github.com/hashicorp/terraform-registry-address v0.2.3/go.mod h1:lFHA76T8jfQteVfT7caREqguFrW3c4MFSPhZB7HHgUM= github.com/hashicorp/terraform-svchost v0.1.1 h1:EZZimZ1GxdqFRinZ1tpJwVxxt49xc/S52uzrw4x0jKQ= github.com/hashicorp/terraform-svchost v0.1.1/go.mod h1:mNsjQfZyf/Jhz35v6/0LWcv26+X7JPS+buii2c9/ctc= github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE= @@ -202,15 +206,15 @@ github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI= github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= -github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU= -github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= +github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8= +github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok= github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/zclconf/go-cty v1.14.0 h1:/Xrd39K7DXbHzlisFP9c4pHao4yyf+/Ug9LEz+Y/yhc= -github.com/zclconf/go-cty v1.14.0/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= +github.com/zclconf/go-cty v1.14.1 h1:t9fyA35fwjjUMcmL5hLER+e/rEPqrbCK1/OSE4SI9KA= +github.com/zclconf/go-cty v1.14.1/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -218,14 +222,14 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= -golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= -golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY= +golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= -golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= +golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= @@ -255,15 +259,15 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= -golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= -golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= +golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= +golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -272,8 +276,8 @@ golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= @@ -287,8 +291,8 @@ google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAs google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= google.golang.org/genproto/googleapis/rpc v0.0.0-20230913181813-007df8e322eb h1:Isk1sSH7bovx8Rti2wZK0UZF6oraBDK74uoyLEEVFN0= google.golang.org/genproto/googleapis/rpc v0.0.0-20230913181813-007df8e322eb/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= -google.golang.org/grpc v1.58.1 h1:OL+Vz23DTtrrldqHK49FUOPHyY75rvFqJfXC84NYW58= -google.golang.org/grpc v1.58.1/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= +google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk= +google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= diff --git a/internal/customvalidator/attributeneedstobesetvalidator.go b/internal/customvalidator/attributeneedstobesetvalidator.go new file mode 100644 index 0000000..c66d14e --- /dev/null +++ b/internal/customvalidator/attributeneedstobesetvalidator.go @@ -0,0 +1,84 @@ +package customvalidator + +import ( + "context" + "fmt" + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" +) + +var _ validator.String = &attributeNeedsToBeSetValidator{} + +type attributeNeedsToBeSetValidator struct { + pathToBeSet path.Expression + value string +} + +func (s attributeNeedsToBeSetValidator) Description(_ context.Context) string { + finalStep, _ := s.pathToBeSet.Steps().LastStep() + return fmt.Sprintf("Attribute \"%s\" needs to be set when value of the current field is \"%s\"", finalStep.String(), s.value) +} + +func (s attributeNeedsToBeSetValidator) MarkdownDescription(ctx context.Context) string { + return s.Description(ctx) +} + +func (s attributeNeedsToBeSetValidator) ValidateString(ctx context.Context, request validator.StringRequest, response *validator.StringResponse) { + // If the current attribute configuration is null or unknown, there + // cannot be any value comparisons, so exit early without error. + if request.ConfigValue.IsNull() || request.ConfigValue.IsUnknown() { + return + } + + // field is not set to the expected value, so we skip + if request.ConfigValue.ValueString() != s.value { + return + } + + // Combine the given path expressions with the current attribute path + // expression. This call automatically handles relative and absolute + // expressions. + expression := request.PathExpression.Merge(s.pathToBeSet) + + // Find paths matching the expression in the configuration data. + matchedPaths, diags := request.Config.PathMatches(ctx, expression) + + response.Diagnostics.Append(diags...) + + // Collect all errors + if diags.HasError() { + return + } + + for _, matchedPath := range matchedPaths { + var matchedPathValue attr.Value + + diags = request.Config.GetAttribute(ctx, matchedPath, &matchedPathValue) + + response.Diagnostics.Append(diags...) + + // Collect all errors + if diags.HasError() { + continue + } + + // If the matched path value is null or unknown, we cannot compare + // values, so continue to other matched paths. + if matchedPathValue.IsNull() || matchedPathValue.IsUnknown() { + finalStep, _ := expression.Steps().LastStep() + response.Diagnostics.AddAttributeError( + request.Path, + "Attribute Value Is Not Set", + fmt.Sprintf("The attribute \"%s\" needs to be set as the value of \"%s\" is \"%s\".", finalStep.String(), request.Path.String(), s.value), + ) + } + } +} + +func AttributeNeedsToBeSetValidator(pathToBeSet path.Expression, value string) validator.String { + return attributeNeedsToBeSetValidator{ + pathToBeSet: pathToBeSet, + value: value, + } +} diff --git a/internal/customvalidator/stringallowedwhensetvalidator.go b/internal/customvalidator/stringallowedwhensetvalidator.go index 1014d8b..8598074 100644 --- a/internal/customvalidator/stringallowedwhensetvalidator.go +++ b/internal/customvalidator/stringallowedwhensetvalidator.go @@ -74,7 +74,7 @@ func (s stringAllowedWhenSetValidator) ValidateString(ctx context.Context, reque response.Diagnostics.Append(diags...) - // If the matched path value was not able to be converted from + // If the matched path value was not able to convert from // attr.Value to the intended types.Int64 implementation, it most // likely means that the path expression was not pointing at a // types.Int64Type attribute. Collect the error and continue to diff --git a/internal/customvalidator/whenothervalueexistlistvalidator.go b/internal/customvalidator/whenothervalueexistlistvalidator.go new file mode 100644 index 0000000..14283a3 --- /dev/null +++ b/internal/customvalidator/whenothervalueexistlistvalidator.go @@ -0,0 +1,76 @@ +package customvalidator + +import ( + "context" + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" +) + +var _ validator.List = &whenOtherValueExistListValidator{} + +type whenOtherValueExistListValidator struct { + expression path.Expression + listValidator validator.List +} + +func (l whenOtherValueExistListValidator) Description(_ context.Context) string { + return "Validates a list when a given property is set" +} + +func (l whenOtherValueExistListValidator) MarkdownDescription(ctx context.Context) string { + return l.Description(ctx) +} + +func (l whenOtherValueExistListValidator) ValidateList(ctx context.Context, request validator.ListRequest, response *validator.ListResponse) { + // If the current attribute configuration is null or unknown, there + // cannot be any value comparisons, so exit early without error. + if request.ConfigValue.IsNull() || request.ConfigValue.IsUnknown() { + return + } + + // Combine the given path expressions with the current attribute path + // expression. This call automatically handles relative and absolute + // expressions. + expression := request.PathExpression.Merge(l.expression) + + // Find paths matching the expression in the configuration data. + matchedPaths, diags := request.Config.PathMatches(ctx, expression) + + response.Diagnostics.Append(diags...) + + // Collect all errors + if diags.HasError() { + return + } + + for _, matchedPath := range matchedPaths { + var matchedPathValue attr.Value + + diags = request.Config.GetAttribute(ctx, matchedPath, &matchedPathValue) + + response.Diagnostics.Append(diags...) + + // Collect all errors + if diags.HasError() { + continue + } + + // If the matched path value is null or unknown, we cannot compare + // values, so continue to other matched paths. + if matchedPathValue.IsNull() || matchedPathValue.IsUnknown() { + continue + } + + // when the matched path has a value we will execute the given list validation + + l.listValidator.ValidateList(ctx, request, response) + } +} + +func WhenOtherValueExistListValidator(expression path.Expression, listValidator validator.List) validator.List { + return whenOtherValueExistListValidator{ + expression: expression, + listValidator: listValidator, + } +} diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 25e7ab6..a40245c 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/types" "github.com/labd/contentful-go" + "github.com/labd/terraform-provider-contentful/internal/resources/app_definition" "github.com/labd/terraform-provider-contentful/internal/resources/contenttype" "github.com/labd/terraform-provider-contentful/internal/utils" "os" @@ -92,7 +93,8 @@ func (c contentfulProvider) Configure(ctx context.Context, request provider.Conf } data := utils.ProviderData{ - Client: cma, + Client: cma, + OrganizationId: organizationId, } response.ResourceData = data @@ -106,5 +108,6 @@ func (c contentfulProvider) DataSources(_ context.Context) []func() datasource.D func (c contentfulProvider) Resources(_ context.Context) []func() resource.Resource { return []func() resource.Resource{ contenttype.NewContentTypeResource, + app_definition.NewAppDefinitionResource, } } diff --git a/internal/resources/app_definition/bundle.zip b/internal/resources/app_definition/bundle.zip new file mode 100644 index 0000000000000000000000000000000000000000..d273e6616102c5ca78af490b34267fd1ffb5a0f7 GIT binary patch literal 390 zcmWIWW@Zs#-~d9_+SYIeC~#tAVBlgA_cF^*l>=fBU0T7- zz{oQ5V7(%XrqW%H-T?2s76YEU#a!mEm9E^?5#qZLJ>!Om_s<0h4tMsQG>|Hd^xpRL z{^!ka*;ChFKeZu)Cpmp~bHmHyl77onB{JVE=;~d=QFn0DMyt)Q@7SODuzi}rCgb)G zJD)9LtMNOv^4mP8T^5g=ZN8s>5Iku`!VB~M#=GInn-1?i<2Q5NtDt)|6GM-`uMKus zV0(;vnQdUgfykW>SDT9U1f}N5-cz2dYUyxd=A_NDW`P=$Rxsy2pMEKP{_c*l131V_;3pFW@Q8EU Date: Fri, 8 Dec 2023 13:06:15 +0100 Subject: [PATCH 165/192] PLT-747 - Reorder of fields is not working (#22) --- .../unreleased/Fixed-20231208-125450.yaml | 3 ++ internal/resources/contenttype/model.go | 7 +++- .../resources/contenttype/resource_test.go | 35 ++++++++++++++++++- 3 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 .changes/unreleased/Fixed-20231208-125450.yaml diff --git a/.changes/unreleased/Fixed-20231208-125450.yaml b/.changes/unreleased/Fixed-20231208-125450.yaml new file mode 100644 index 0000000..06c5d6c --- /dev/null +++ b/.changes/unreleased/Fixed-20231208-125450.yaml @@ -0,0 +1,3 @@ +kind: Fixed +body: Fixed wrong behaviour when fields where sorted +time: 2023-12-08T12:54:50.364686+01:00 diff --git a/internal/resources/contenttype/model.go b/internal/resources/contenttype/model.go index 247783c..cca53cb 100644 --- a/internal/resources/contenttype/model.go +++ b/internal/resources/contenttype/model.go @@ -561,7 +561,7 @@ func (c *ContentType) Equal(n *contentful.ContentType) bool { return false } - for _, field := range c.Fields { + for idxOrg, field := range c.Fields { idx := pie.FindFirstUsing(n.Fields, func(f *contentful.Field) bool { return f.ID == field.Id.ValueString() }) @@ -573,6 +573,11 @@ func (c *ContentType) Equal(n *contentful.ContentType) bool { if !field.Equal(n.Fields[idx]) { return false } + + // field was moved, it is the same as before but different position + if idxOrg != idx { + return false + } } return true diff --git a/internal/resources/contenttype/resource_test.go b/internal/resources/contenttype/resource_test.go index 3381ab6..0122a93 100644 --- a/internal/resources/contenttype/resource_test.go +++ b/internal/resources/contenttype/resource_test.go @@ -36,11 +36,20 @@ func TestContentTypeResource_Create(t *testing.T) { //todo check in contentful directly if the type looks like this ), }, + { + Config: testContentTypeUpdateWithDifferentOrderOfFields("acctest_content_type", os.Getenv("CONTENTFUL_SPACE_ID")), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "name", "tf_test1"), + resource.TestCheckResourceAttr(resourceName, "version", "4"), + resource.TestCheckResourceAttr(resourceName, "version_controls", "0"), + //todo check in contentful directly if the type looks like this + ), + }, { Config: testContentTypeUpdate("acctest_content_type", os.Getenv("CONTENTFUL_SPACE_ID")), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(resourceName, "name", "tf_test1"), - resource.TestCheckResourceAttr(resourceName, "version", "2"), + resource.TestCheckResourceAttr(resourceName, "version", "6"), resource.TestCheckResourceAttr(resourceName, "version_controls", "2"), //todo check in contentful directly if the type looks like this ), @@ -138,6 +147,30 @@ func testContentTypeWithId(identifier string, spaceId string) string { }) } +func testContentTypeUpdateWithDifferentOrderOfFields(identifier string, spaceId string) string { + return utils.HCLTemplate(` + resource "contentful_contenttype" "{{ .identifier }}" { + space_id = "{{ .spaceId }}" + name = "tf_test1" + description = "Terraform Acc Test Content Type description change" + display_field = "field1" + fields = [{ + id = "field3" + name = "Field 3 new field" + required = true + type = "Integer" + },{ + id = "field1" + name = "Field 1 name change" + required = true + type = "Text" + } ] +}`, map[string]any{ + "identifier": identifier, + "spaceId": spaceId, + }) +} + func testContentTypeUpdate(identifier string, spaceId string) string { return utils.HCLTemplate(` resource "contentful_contenttype" "{{ .identifier }}" { From 4932700a52600bb345aa66b69779c7bab4f7e4f5 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 8 Dec 2023 13:07:48 +0100 Subject: [PATCH 166/192] Release v1.3.0 (#21) Co-authored-by: Engerim --- .changes/unreleased/Added-20231208-120207.yaml | 3 --- .changes/unreleased/Fixed-20231208-125450.yaml | 3 --- .changes/v1.3.0.md | 5 +++++ CHANGELOG.md | 6 ++++++ 4 files changed, 11 insertions(+), 6 deletions(-) delete mode 100644 .changes/unreleased/Added-20231208-120207.yaml delete mode 100644 .changes/unreleased/Fixed-20231208-125450.yaml create mode 100644 .changes/v1.3.0.md diff --git a/.changes/unreleased/Added-20231208-120207.yaml b/.changes/unreleased/Added-20231208-120207.yaml deleted file mode 100644 index e99ea12..0000000 --- a/.changes/unreleased/Added-20231208-120207.yaml +++ /dev/null @@ -1,3 +0,0 @@ -kind: Added -body: Add support app configuration in the organization -time: 2023-12-08T12:02:07.240628+01:00 diff --git a/.changes/unreleased/Fixed-20231208-125450.yaml b/.changes/unreleased/Fixed-20231208-125450.yaml deleted file mode 100644 index 06c5d6c..0000000 --- a/.changes/unreleased/Fixed-20231208-125450.yaml +++ /dev/null @@ -1,3 +0,0 @@ -kind: Fixed -body: Fixed wrong behaviour when fields where sorted -time: 2023-12-08T12:54:50.364686+01:00 diff --git a/.changes/v1.3.0.md b/.changes/v1.3.0.md new file mode 100644 index 0000000..14b01e5 --- /dev/null +++ b/.changes/v1.3.0.md @@ -0,0 +1,5 @@ +## v1.3.0 - 2023-12-08 +### Added +* Add support app configuration in the organization +### Fixed +* Fixed wrong behaviour when fields where sorted diff --git a/CHANGELOG.md b/CHANGELOG.md index 525e9cb..3b5f3cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,12 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), and is generated by [Changie](https://github.com/miniscruff/changie). +## v1.3.0 - 2023-12-08 +### Added +* Add support app configuration in the organization +### Fixed +* Fixed wrong behaviour when fields where sorted + ## v1.2.1 - 2023-11-14 ### Fixed * Fixed field type validation to allow new fields in the middle From f458b7aeb2cf068895266364675aa76529bf2af3 Mon Sep 17 00:00:00 2001 From: Alexander Miehe Date: Fri, 15 Dec 2023 12:16:55 +0100 Subject: [PATCH 167/192] PLT-751 - Add support for app_installation (#23) * allow to install apps in different environments * improve test cases by checking also against contentful * improve documentation by adding the new resources --- .../unreleased/Added-20231215-115352.yaml | 3 + contentful/resource_contentful_locale_test.go | 7 +- docs/index.md | 6 +- docs/resources/app_definition.md | 85 ++++ docs/resources/app_installation.md | 47 +++ docs/resources/contenttype.md | 239 +++++++++-- docs/resources/locale.md | 4 +- .../contentful_app_definition/resource.tf | 6 + .../contentful_app_installation/resource.tf | 13 + .../contentful_contenttype/resource.tf | 40 +- .../resources/contentful_locale/resource.tf | 3 +- go.mod | 3 +- go.sum | 6 +- internal/custommodifier/stringdefault.go | 40 ++ internal/provider/provider.go | 2 + internal/resources/app_definition/resource.go | 1 - .../resources/app_definition/resource_test.go | 143 +++---- .../app_definition/test_resources/create.tf | 5 + .../app_definition/test_resources/update.tf | 5 + .../test_resources/update_to_src.tf | 6 + internal/resources/app_installation/model.go | 49 +++ .../resources/app_installation/resource.go | 244 +++++++++++ .../app_installation/resource_test.go | 124 ++++++ .../test_resources/with_terms.tf | 14 + .../test_resources/without_terms.tf | 10 + internal/resources/contenttype/model.go | 111 ++++- internal/resources/contenttype/resource.go | 67 ++- .../resources/contenttype/resource_test.go | 381 +++++++++++------- .../test_resources/changed_order.tf | 17 + .../contenttype/test_resources/create.tf | 18 + .../contenttype/test_resources/link_config.tf | 51 +++ .../contenttype/test_resources/update.tf | 26 ++ internal/utils/hcl.go | 16 + 33 files changed, 1471 insertions(+), 321 deletions(-) create mode 100644 .changes/unreleased/Added-20231215-115352.yaml create mode 100644 docs/resources/app_definition.md create mode 100644 docs/resources/app_installation.md create mode 100644 examples/resources/contentful_app_definition/resource.tf create mode 100644 examples/resources/contentful_app_installation/resource.tf create mode 100644 internal/custommodifier/stringdefault.go create mode 100644 internal/resources/app_definition/test_resources/create.tf create mode 100644 internal/resources/app_definition/test_resources/update.tf create mode 100644 internal/resources/app_definition/test_resources/update_to_src.tf create mode 100644 internal/resources/app_installation/model.go create mode 100644 internal/resources/app_installation/resource.go create mode 100644 internal/resources/app_installation/resource_test.go create mode 100644 internal/resources/app_installation/test_resources/with_terms.tf create mode 100644 internal/resources/app_installation/test_resources/without_terms.tf create mode 100644 internal/resources/contenttype/test_resources/changed_order.tf create mode 100644 internal/resources/contenttype/test_resources/create.tf create mode 100644 internal/resources/contenttype/test_resources/link_config.tf create mode 100644 internal/resources/contenttype/test_resources/update.tf diff --git a/.changes/unreleased/Added-20231215-115352.yaml b/.changes/unreleased/Added-20231215-115352.yaml new file mode 100644 index 0000000..882d1c7 --- /dev/null +++ b/.changes/unreleased/Added-20231215-115352.yaml @@ -0,0 +1,3 @@ +kind: Added +body: Add support for app_installations +time: 2023-12-15T11:53:52.030953+01:00 diff --git a/contentful/resource_contentful_locale_test.go b/contentful/resource_contentful_locale_test.go index e98da56..596153c 100644 --- a/contentful/resource_contentful_locale_test.go +++ b/contentful/resource_contentful_locale_test.go @@ -1,7 +1,7 @@ package contentful import ( - "encoding/json" + "errors" "fmt" "testing" @@ -138,9 +138,8 @@ func testAccContentfulLocaleDestroy(s *terraform.State) error { _, err := client.Locales.Get(spaceID, localeID) - // This is caused by a bug in the client library that tries to cast - // error.details to a map but it is a string in this case - if _, ok := err.(*json.UnmarshalTypeError); ok { + var notFoundError contentful.NotFoundError + if errors.As(err, ¬FoundError) { return nil } diff --git a/docs/index.md b/docs/index.md index 85f8c5e..1296505 100644 --- a/docs/index.md +++ b/docs/index.md @@ -15,7 +15,7 @@ description: |- ## Schema -### Required +### Optional -- `cma_token` (String) The Contentful Management API token -- `organization_id` (String) The organization ID +- `cma_token` (String, Sensitive) The Contentful Management API token +- `organization_id` (String, Sensitive) The organization ID diff --git a/docs/resources/app_definition.md b/docs/resources/app_definition.md new file mode 100644 index 0000000..810a28a --- /dev/null +++ b/docs/resources/app_definition.md @@ -0,0 +1,85 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "contentful_app_definition Resource - terraform-provider-contentful" +subcategory: "" +description: |- + Todo for explaining app definition +--- + +# contentful_app_definition (Resource) + +Todo for explaining app definition + +## Example Usage + +```terraform +resource "contentful_app_definition" "example_app_definition" { + name = "test_app_definition" + use_bundle = false + src = "http://localhost:3000" + locations = [{ location = "app-config" }, { location = "dialog" }, { location = "entry-editor" }] +} +``` + + +## Schema + +### Required + +- `locations` (Attributes List) (see [below for nested schema](#nestedatt--locations)) +- `name` (String) +- `use_bundle` (Boolean) + +### Optional + +- `src` (String) + +### Read-Only + +- `bundle_id` (String) +- `id` (String) app definition id + + +### Nested Schema for `locations` + +Required: + +- `location` (String) + +Optional: + +- `field_types` (Attributes List) (see [below for nested schema](#nestedatt--locations--field_types)) +- `navigation_item` (Attributes) (see [below for nested schema](#nestedatt--locations--navigation_item)) + + +### Nested Schema for `locations.field_types` + +Required: + +- `type` (String) + +Optional: + +- `items` (Attributes) (see [below for nested schema](#nestedatt--locations--field_types--items)) +- `link_type` (String) + + +### Nested Schema for `locations.field_types.items` + +Required: + +- `type` (String) + +Optional: + +- `link_type` (String) + + + + +### Nested Schema for `locations.navigation_item` + +Required: + +- `name` (String) +- `path` (String) diff --git a/docs/resources/app_installation.md b/docs/resources/app_installation.md new file mode 100644 index 0000000..605359e --- /dev/null +++ b/docs/resources/app_installation.md @@ -0,0 +1,47 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "contentful_app_installation Resource - terraform-provider-contentful" +subcategory: "" +description: |- + Todo for explaining app installation +--- + +# contentful_app_installation (Resource) + +Todo for explaining app installation + +## Example Usage + +```terraform +resource "contentful_app_installation" "example_app_installation" { + space_id = "space-id" + environment = "master" + + app_definition_id = contentful_app_definition.example_app_definition.id + + parameters = jsonencode({ + "example" : "one", + "nested" : { + "example" : "two" + } + }) +} +``` + + +## Schema + +### Required + +- `app_definition_id` (String) app definition id +- `environment` (String) +- `parameters` (String) Parameters needed for the installation of the app in the given space, like credentials or other configuration parameters +- `space_id` (String) space id + +### Optional + +- `accepted_terms` (List of String) List of needed terms to accept to install the app + +### Read-Only + +- `id` (String) The ID of this resource. diff --git a/docs/resources/contenttype.md b/docs/resources/contenttype.md index 73317da..d9d4d6d 100644 --- a/docs/resources/contenttype.md +++ b/docs/resources/contenttype.md @@ -3,45 +3,65 @@ page_title: "contentful_contenttype Resource - terraform-provider-contentful" subcategory: "" description: |- - + Todo for explaining contenttype --- # contentful_contenttype (Resource) - +Todo for explaining contenttype ## Example Usage ```terraform resource "contentful_contenttype" "example_contenttype" { - space_id = "space-id" - name = "tf_linked" - description = "content type description" - display_field = "asset_field" - field { + space_id = "space-id" + environment = "master" + id = "tf_linked" + name = "tf_linked" + description = "content type description" + display_field = "asset_field" + manage_field_controls = true + fields = [{ id = "asset_field" name = "Asset Field" type = "Array" - items { + items = { type = "Link" link_type = "Asset" } required = true - } - field { + }, { id = "entry_link_field" name = "Entry Link Field" type = "Link" link_type = "Entry" + validations = [{ + link_content_type = [ + contentful_contenttype.some_other_content_type.id + ] + } + ] + required = false + }, { + id = "select", + name = "Select Field", + type = "Symbol", + required = true, validations = [ - jsonencode({ - linkContentType = [ - contentful_contenttype.some_other_content_type.id + { + in = [ + "choice 1", + "choice 2", + "choice 3", + "choice 4" ] - }) + } ] - required = false - } + control = { + widget_id = "radio" + widget_namespace = "builtin" + } + }] } ``` @@ -51,49 +71,210 @@ resource "contentful_contenttype" "example_contenttype" { ### Required - `display_field` (String) -- `field` (Block List, Min: 1) (see [below for nested schema](#nestedblock--field)) +- `fields` (Attributes List) (see [below for nested schema](#nestedatt--fields)) - `name` (String) -- `space_id` (String) +- `space_id` (String) space id ### Optional - `description` (String) +- `environment` (String) +- `id` (String) content type id +- `manage_field_controls` (Boolean) +- `sidebar` (Attributes List) (see [below for nested schema](#nestedatt--sidebar)) ### Read-Only -- `id` (String) The ID of this resource. - `version` (Number) +- `version_controls` (Number) - -### Nested Schema for `field` + +### Nested Schema for `fields` Required: +- `id` (String) - `name` (String) - `type` (String) Optional: +- `control` (Attributes) (see [below for nested schema](#nestedatt--fields--control)) +- `default_value` (Attributes) (see [below for nested schema](#nestedatt--fields--default_value)) - `disabled` (Boolean) -- `items` (Block List, Max: 1) (see [below for nested schema](#nestedblock--field--items)) +- `items` (Attributes) (see [below for nested schema](#nestedatt--fields--items)) - `link_type` (String) - `localized` (Boolean) - `omitted` (Boolean) - `required` (Boolean) -- `validations` (List of String) +- `validations` (Attributes List) (see [below for nested schema](#nestedatt--fields--validations)) + + +### Nested Schema for `fields.control` + +Required: + +- `widget_id` (String) +- `widget_namespace` (String) + +Optional: + +- `settings` (Attributes) (see [below for nested schema](#nestedatt--fields--control--settings)) + + +### Nested Schema for `fields.control.settings` + +Optional: + +- `ampm` (String) +- `bulk_editing` (Boolean) +- `false_label` (String) +- `format` (String) +- `help_text` (String) +- `stars` (Number) +- `tracking_field_id` (String) +- `true_label` (String) + + + + +### Nested Schema for `fields.default_value` + +Optional: -Read-Only: +- `bool` (Map of Boolean) +- `string` (Map of String) -- `id` (String) The ID of this resource. - -### Nested Schema for `field.items` + +### Nested Schema for `fields.items` Required: -- `link_type` (String) - `type` (String) Optional: -- `validations` (List of String) +- `link_type` (String) +- `validations` (Attributes List) (see [below for nested schema](#nestedatt--fields--items--validations)) + + +### Nested Schema for `fields.items.validations` + +Optional: + +- `asset_file_size` (Attributes) (see [below for nested schema](#nestedatt--fields--items--validations--asset_file_size)) +- `enabled_marks` (List of String) +- `enabled_node_types` (List of String) +- `in` (List of String) +- `link_content_type` (List of String) +- `link_mimetype_group` (List of String) +- `message` (String) +- `range` (Attributes) (see [below for nested schema](#nestedatt--fields--items--validations--range)) +- `regexp` (Attributes) (see [below for nested schema](#nestedatt--fields--items--validations--regexp)) +- `size` (Attributes) (see [below for nested schema](#nestedatt--fields--items--validations--size)) +- `unique` (Boolean) + + +### Nested Schema for `fields.items.validations.unique` + +Optional: + +- `max` (Number) +- `min` (Number) + + + +### Nested Schema for `fields.items.validations.unique` + +Optional: + +- `max` (Number) +- `min` (Number) + + + +### Nested Schema for `fields.items.validations.unique` + +Optional: + +- `pattern` (String) + + + +### Nested Schema for `fields.items.validations.unique` + +Optional: + +- `max` (Number) +- `min` (Number) + + + + + +### Nested Schema for `fields.validations` + +Optional: + +- `asset_file_size` (Attributes) (see [below for nested schema](#nestedatt--fields--validations--asset_file_size)) +- `enabled_marks` (List of String) +- `enabled_node_types` (List of String) +- `in` (List of String) +- `link_content_type` (List of String) +- `link_mimetype_group` (List of String) +- `message` (String) +- `range` (Attributes) (see [below for nested schema](#nestedatt--fields--validations--range)) +- `regexp` (Attributes) (see [below for nested schema](#nestedatt--fields--validations--regexp)) +- `size` (Attributes) (see [below for nested schema](#nestedatt--fields--validations--size)) +- `unique` (Boolean) + + +### Nested Schema for `fields.validations.asset_file_size` + +Optional: + +- `max` (Number) +- `min` (Number) + + + +### Nested Schema for `fields.validations.range` + +Optional: + +- `max` (Number) +- `min` (Number) + + + +### Nested Schema for `fields.validations.regexp` + +Optional: + +- `pattern` (String) + + + +### Nested Schema for `fields.validations.size` + +Optional: + +- `max` (Number) +- `min` (Number) + + + + + +### Nested Schema for `sidebar` + +Required: + +- `widget_id` (String) +- `widget_namespace` (String) + +Optional: + +- `disabled` (Boolean) +- `settings` (String) diff --git a/docs/resources/locale.md b/docs/resources/locale.md index f27d118..de1ebb2 100644 --- a/docs/resources/locale.md +++ b/docs/resources/locale.md @@ -14,7 +14,8 @@ description: |- ```terraform resource "contentful_locale" "example_locale" { - space_id = "spaced-id" + space_id = "spaced-id" + environment = "master" name = "locale-name" code = "de" @@ -38,6 +39,7 @@ resource "contentful_locale" "example_locale" { - `cda` (Boolean) - `cma` (Boolean) +- `environment` (String) - `fallback_code` (String) - `optional` (Boolean) diff --git a/examples/resources/contentful_app_definition/resource.tf b/examples/resources/contentful_app_definition/resource.tf new file mode 100644 index 0000000..2339e01 --- /dev/null +++ b/examples/resources/contentful_app_definition/resource.tf @@ -0,0 +1,6 @@ +resource "contentful_app_definition" "example_app_definition" { + name = "test_app_definition" + use_bundle = false + src = "http://localhost:3000" + locations = [{ location = "app-config" }, { location = "dialog" }, { location = "entry-editor" }] +} \ No newline at end of file diff --git a/examples/resources/contentful_app_installation/resource.tf b/examples/resources/contentful_app_installation/resource.tf new file mode 100644 index 0000000..3a33913 --- /dev/null +++ b/examples/resources/contentful_app_installation/resource.tf @@ -0,0 +1,13 @@ +resource "contentful_app_installation" "example_app_installation" { + space_id = "space-id" + environment = "master" + + app_definition_id = contentful_app_definition.example_app_definition.id + + parameters = jsonencode({ + "example" : "one", + "nested" : { + "example" : "two" + } + }) +} \ No newline at end of file diff --git a/examples/resources/contentful_contenttype/resource.tf b/examples/resources/contentful_contenttype/resource.tf index 983f99d..08cedf2 100644 --- a/examples/resources/contentful_contenttype/resource.tf +++ b/examples/resources/contentful_contenttype/resource.tf @@ -1,9 +1,12 @@ resource "contentful_contenttype" "example_contenttype" { - space_id = "space-id" - name = "tf_linked" - description = "content type description" - display_field = "asset_field" - fields =[{ + space_id = "space-id" + environment = "master" + id = "tf_linked" + name = "tf_linked" + description = "content type description" + display_field = "asset_field" + manage_field_controls = true + fields = [{ id = "asset_field" name = "Asset Field" type = "Array" @@ -12,17 +15,36 @@ resource "contentful_contenttype" "example_contenttype" { link_type = "Asset" } required = true - }, { + }, { id = "entry_link_field" name = "Entry Link Field" type = "Link" link_type = "Entry" validations = [{ - link_content_type = [ - contentful_contenttype.some_other_content_type.id - ] + link_content_type = [ + contentful_contenttype.some_other_content_type.id + ] } ] required = false + }, { + id = "select", + name = "Select Field", + type = "Symbol", + required = true, + validations = [ + { + in = [ + "choice 1", + "choice 2", + "choice 3", + "choice 4" + ] + } + ] + control = { + widget_id = "radio" + widget_namespace = "builtin" + } }] } \ No newline at end of file diff --git a/examples/resources/contentful_locale/resource.tf b/examples/resources/contentful_locale/resource.tf index e42a48c..ea6a0c0 100644 --- a/examples/resources/contentful_locale/resource.tf +++ b/examples/resources/contentful_locale/resource.tf @@ -1,5 +1,6 @@ resource "contentful_locale" "example_locale" { - space_id = "spaced-id" + space_id = "spaced-id" + environment = "master" name = "locale-name" code = "de" diff --git a/go.mod b/go.mod index 8fc5a86..e02f1a0 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/elliotchance/pie/v2 v2.8.0 github.com/hashicorp/terraform-plugin-docs v0.16.0 github.com/hashicorp/terraform-plugin-framework v1.4.2 + github.com/hashicorp/terraform-plugin-framework-jsontypes v0.1.0 github.com/hashicorp/terraform-plugin-framework-validators v0.12.0 github.com/hashicorp/terraform-plugin-mux v0.12.0 github.com/hashicorp/terraform-plugin-testing v1.6.0 @@ -85,4 +86,4 @@ require ( moul.io/http2curl v1.0.1-0.20190925090545-5cd742060b0e // indirect ) -replace github.com/labd/contentful-go v0.5.3 => github.com/flaconi/contentful-go v0.5.3-0.20231208091000-136be0669443 +replace github.com/labd/contentful-go v0.5.3 => github.com/flaconi/contentful-go v0.5.3-0.20231215085749-a6bd885d770b diff --git a/go.sum b/go.sum index 639b2bf..43f7e21 100644 --- a/go.sum +++ b/go.sum @@ -43,8 +43,8 @@ github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5Kwzbycv github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= -github.com/flaconi/contentful-go v0.5.3-0.20231208091000-136be0669443 h1:Pk1gUs5HYHbjBmuUSEcj6g0RQrquBdehHAzIe/supqo= -github.com/flaconi/contentful-go v0.5.3-0.20231208091000-136be0669443/go.mod h1:ciVUTFqeUtSSNjuEQnYLqbXvAlPu/aiPU4CsUc6Ug80= +github.com/flaconi/contentful-go v0.5.3-0.20231215085749-a6bd885d770b h1:J/OqzU6GRbmRIjgl2OjjvhbokKgmBCR189c1xGbgAdY= +github.com/flaconi/contentful-go v0.5.3-0.20231215085749-a6bd885d770b/go.mod h1:ciVUTFqeUtSSNjuEQnYLqbXvAlPu/aiPU4CsUc6Ug80= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= @@ -106,6 +106,8 @@ github.com/hashicorp/terraform-plugin-docs v0.16.0 h1:UmxFr3AScl6Wged84jndJIfFcc github.com/hashicorp/terraform-plugin-docs v0.16.0/go.mod h1:M3ZrlKBJAbPMtNOPwHicGi1c+hZUh7/g0ifT/z7TVfA= github.com/hashicorp/terraform-plugin-framework v1.4.2 h1:P7a7VP1GZbjc4rv921Xy5OckzhoiO3ig6SGxwelD2sI= github.com/hashicorp/terraform-plugin-framework v1.4.2/go.mod h1:GWl3InPFZi2wVQmdVnINPKys09s9mLmTZr95/ngLnbY= +github.com/hashicorp/terraform-plugin-framework-jsontypes v0.1.0 h1:b8vZYB/SkXJT4YPbT3trzE6oJ7dPyMy68+9dEDKsJjE= +github.com/hashicorp/terraform-plugin-framework-jsontypes v0.1.0/go.mod h1:tP9BC3icoXBz72evMS5UTFvi98CiKhPdXF6yLs1wS8A= github.com/hashicorp/terraform-plugin-framework-validators v0.12.0 h1:HOjBuMbOEzl7snOdOoUfE2Jgeto6JOjLVQ39Ls2nksc= github.com/hashicorp/terraform-plugin-framework-validators v0.12.0/go.mod h1:jfHGE/gzjxYz6XoUwi/aYiiKrJDeutQNUtGQXkaHklg= github.com/hashicorp/terraform-plugin-go v0.19.1 h1:lf/jTGTeELcz5IIbn/94mJdmnTjRYm6S6ct/JqCSr50= diff --git a/internal/custommodifier/stringdefault.go b/internal/custommodifier/stringdefault.go new file mode 100644 index 0000000..73ed7d6 --- /dev/null +++ b/internal/custommodifier/stringdefault.go @@ -0,0 +1,40 @@ +package custommodifier + +import ( + "context" + "fmt" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +// From https://developer.hashicorp.com/terraform/plugin/framework/resources/plan-modification#creating-attribute-plan-modifiers + +var _ planmodifier.String = stringDefaultModifier{} +var _ planmodifier.Describer = stringDefaultModifier{} + +type stringDefaultModifier struct { + Default string +} + +// Description returns a human-readable description of the plan modifier. +func (m stringDefaultModifier) Description(_ context.Context) string { + return fmt.Sprintf("If value is not configured, defaults to %s", m.Default) +} + +// MarkdownDescription returns a markdown description of the plan modifier. +func (m stringDefaultModifier) MarkdownDescription(ctx context.Context) string { + return m.Description(ctx) +} + +func (m stringDefaultModifier) PlanModifyString(_ context.Context, _ planmodifier.StringRequest, resp *planmodifier.StringResponse) { + // If the value is unknown or known, do not set default value. + if resp.PlanValue.IsNull() || resp.PlanValue.IsUnknown() { + resp.PlanValue = types.StringValue(m.Default) + } +} + +func StringDefault(defaultValue string) planmodifier.String { + return stringDefaultModifier{ + Default: defaultValue, + } +} diff --git a/internal/provider/provider.go b/internal/provider/provider.go index a40245c..5af834e 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -9,6 +9,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/types" "github.com/labd/contentful-go" "github.com/labd/terraform-provider-contentful/internal/resources/app_definition" + "github.com/labd/terraform-provider-contentful/internal/resources/app_installation" "github.com/labd/terraform-provider-contentful/internal/resources/contenttype" "github.com/labd/terraform-provider-contentful/internal/utils" "os" @@ -109,5 +110,6 @@ func (c contentfulProvider) Resources(_ context.Context) []func() resource.Resou return []func() resource.Resource{ contenttype.NewContentTypeResource, app_definition.NewAppDefinitionResource, + app_installation.NewAppInstallationResource, } } diff --git a/internal/resources/app_definition/resource.go b/internal/resources/app_definition/resource.go index 4bc73f4..af519f7 100644 --- a/internal/resources/app_definition/resource.go +++ b/internal/resources/app_definition/resource.go @@ -49,7 +49,6 @@ func (e *appDefinitionResource) Schema(_ context.Context, _ resource.SchemaReque Description: "Todo for explaining app definition", Attributes: map[string]schema.Attribute{ "id": schema.StringAttribute{ - Optional: true, Computed: true, Description: "app definition id", PlanModifiers: []planmodifier.String{ diff --git a/internal/resources/app_definition/resource_test.go b/internal/resources/app_definition/resource_test.go index 12b531e..9e8b899 100644 --- a/internal/resources/app_definition/resource_test.go +++ b/internal/resources/app_definition/resource_test.go @@ -17,6 +17,8 @@ import ( "testing" ) +type assertFunc func(*testing.T, *contentful.AppDefinition) + func TestAppDefinitionResource_Create(t *testing.T) { resourceName := "contentful_app_definition.acctest_app_definition" resource.Test(t, resource.TestCase{ @@ -32,25 +34,16 @@ func TestAppDefinitionResource_Create(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "name", "tf_test1"), resource.TestMatchResourceAttr(resourceName, "id", regexp.MustCompile(`^[a-zA-Z0-9-_.]{1,64}$`)), resource.TestMatchResourceAttr(resourceName, "bundle_id", regexp.MustCompile(`^[a-zA-Z0-9-_.]{1,64}$`)), - func(s *terraform.State) error { - result, err := getAppDefinitionFromState(s, resourceName) - if err != nil { - return err - } - if result == nil { - return fmt.Errorf("resource not found") - } - - assert.Nil(t, result.SRC) - assert.EqualValues(t, result.Name, "tf_test1") - assert.Len(t, result.Locations, 1) - assert.EqualValues(t, result.Locations[0].Location, "entry-field") - assert.Len(t, result.Locations[0].FieldTypes, 1) - assert.EqualValues(t, result.Locations[0].FieldTypes[0].Type, "Symbol") - assert.NotNil(t, result.Bundle) - assert.Regexp(t, regexp.MustCompile(`^[a-zA-Z0-9-_.]{1,64}$`), result.Bundle.Sys.ID) - return nil - }, + testAccCheckContentfulAppDefinitionExists(t, resourceName, func(t *testing.T, definition *contentful.AppDefinition) { + assert.Nil(t, definition.SRC) + assert.EqualValues(t, definition.Name, "tf_test1") + assert.Len(t, definition.Locations, 1) + assert.EqualValues(t, definition.Locations[0].Location, "entry-field") + assert.Len(t, definition.Locations[0].FieldTypes, 1) + assert.EqualValues(t, definition.Locations[0].FieldTypes[0].Type, "Symbol") + assert.NotNil(t, definition.Bundle) + assert.Regexp(t, regexp.MustCompile(`^[a-zA-Z0-9-_.]{1,64}$`), definition.Bundle.Sys.ID) + }), ), }, { @@ -59,26 +52,17 @@ func TestAppDefinitionResource_Create(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "name", "tf_test1"), resource.TestMatchResourceAttr(resourceName, "id", regexp.MustCompile(`^[a-zA-Z0-9-_.]{1,64}$`)), resource.TestMatchResourceAttr(resourceName, "bundle_id", regexp.MustCompile(`^[a-zA-Z0-9-_.]{1,64}$`)), - func(s *terraform.State) error { - result, err := getAppDefinitionFromState(s, resourceName) - if err != nil { - return err - } - if result == nil { - return fmt.Errorf("resource not found") - } - - assert.Nil(t, result.SRC) - assert.EqualValues(t, result.Name, "tf_test1") - assert.Len(t, result.Locations, 2) - assert.EqualValues(t, result.Locations[0].Location, "entry-field") - assert.Len(t, result.Locations[0].FieldTypes, 1) - assert.EqualValues(t, result.Locations[1].Location, "dialog") - assert.EqualValues(t, result.Locations[0].FieldTypes[0].Type, "Symbol") - assert.NotNil(t, result.Bundle) - assert.Regexp(t, regexp.MustCompile(`^[a-zA-Z0-9-_.]{1,64}$`), result.Bundle.Sys.ID) - return nil - }, + testAccCheckContentfulAppDefinitionExists(t, resourceName, func(t *testing.T, definition *contentful.AppDefinition) { + assert.Nil(t, definition.SRC) + assert.EqualValues(t, definition.Name, "tf_test1") + assert.Len(t, definition.Locations, 2) + assert.EqualValues(t, definition.Locations[0].Location, "entry-field") + assert.Len(t, definition.Locations[0].FieldTypes, 1) + assert.EqualValues(t, definition.Locations[1].Location, "dialog") + assert.EqualValues(t, definition.Locations[0].FieldTypes[0].Type, "Symbol") + assert.NotNil(t, definition.Bundle) + assert.Regexp(t, regexp.MustCompile(`^[a-zA-Z0-9-_.]{1,64}$`), definition.Bundle.Sys.ID) + }), ), }, { @@ -87,30 +71,33 @@ func TestAppDefinitionResource_Create(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "name", "tf_test1"), resource.TestCheckResourceAttr(resourceName, "src", "http://localhost"), resource.TestCheckNoResourceAttr(resourceName, "bundle_id"), - func(s *terraform.State) error { - result, err := getAppDefinitionFromState(s, resourceName) - if err != nil { - return err - } - if result == nil { - return fmt.Errorf("resource not found") - } - - assert.Equal(t, *result.SRC, "http://localhost") - assert.EqualValues(t, result.Name, "tf_test1") - assert.Len(t, result.Locations, 1) - assert.EqualValues(t, result.Locations[0].Location, "entry-field") - assert.Len(t, result.Locations[0].FieldTypes, 1) - assert.EqualValues(t, result.Locations[0].FieldTypes[0].Type, "Symbol") - assert.Nil(t, result.Bundle) - return nil - }, + testAccCheckContentfulAppDefinitionExists(t, resourceName, func(t *testing.T, definition *contentful.AppDefinition) { + assert.Equal(t, *definition.SRC, "http://localhost") + assert.EqualValues(t, definition.Name, "tf_test1") + assert.Len(t, definition.Locations, 1) + assert.EqualValues(t, definition.Locations[0].Location, "entry-field") + assert.Len(t, definition.Locations[0].FieldTypes, 1) + assert.EqualValues(t, definition.Locations[0].FieldTypes[0].Type, "Symbol") + assert.Nil(t, definition.Bundle) + }), ), }, }, }) } +func testAccCheckContentfulAppDefinitionExists(t *testing.T, resourceName string, assertFunc assertFunc) resource.TestCheckFunc { + return func(s *terraform.State) error { + definition, err := getAppDefinitionFromState(s, resourceName) + if err != nil { + return err + } + + assertFunc(t, definition) + return nil + } +} + func getAppDefinitionFromState(s *terraform.State, resourceName string) (*contentful.AppDefinition, error) { rs, ok := s.RootModule().Resources[resourceName] if !ok { @@ -126,26 +113,6 @@ func getAppDefinitionFromState(s *terraform.State, resourceName string) (*conten return client.AppDefinitions.Get(os.Getenv("CONTENTFUL_ORGANIZATION_ID"), rs.Primary.ID) } -func TestContentTypeResource_Import(t *testing.T) { - resourceName := "contentful_app_definition.acctest_app_definition" - resource.Test(t, resource.TestCase{ - PreCheck: func() { acctest.TestAccPreCheck(t) }, - CheckDestroy: testAccCheckContentfulAppDefinitionDestroy, - ProtoV6ProviderFactories: map[string]func() (tfprotov6.ProviderServer, error){ - "contentful": providerserver.NewProtocol6WithError(provider.New("test", true)), - }, - Steps: []resource.TestStep{ - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - ImportStateId: "3Vpues6ipKGlYIhLi56F1m", - Config: testAppDefinition("acctest_app_definition"), - }, - }, - }) -} - func testAccCheckContentfulAppDefinitionDestroy(s *terraform.State) error { client := acctest.GetClient() @@ -167,35 +134,19 @@ func testAccCheckContentfulAppDefinitionDestroy(s *terraform.State) error { } func testAppDefinition(identifier string) string { - return utils.HCLTemplate(` - resource "contentful_app_definition" "{{ .identifier }}" { - name = "tf_test1" -use_bundle = true -locations = [{location = "entry-field", "field_types" = [{"type" = "Symbol"}]}] -}`, map[string]any{ + return utils.HCLTemplateFromPath("test_resources/create.tf", map[string]any{ "identifier": identifier, }) } func testAppDefinitionUpdateLocation(identifier string) string { - return utils.HCLTemplate(` - resource "contentful_app_definition" "{{ .identifier }}" { - name = "tf_test1" -use_bundle = true -locations = [{location = "entry-field", "field_types" = [{"type" = "Symbol"}]}, {location = "dialog"}] -}`, map[string]any{ + return utils.HCLTemplateFromPath("test_resources/update.tf", map[string]any{ "identifier": identifier, }) } func testAppDefinitionUpdateToSrc(identifier string) string { - return utils.HCLTemplate(` - resource "contentful_app_definition" "{{ .identifier }}" { - name = "tf_test1" -use_bundle = false -locations = [{location = "entry-field", "field_types" = [{"type" = "Symbol"}]}] -src = "http://localhost" -}`, map[string]any{ + return utils.HCLTemplateFromPath("test_resources/update_to_src.tf", map[string]any{ "identifier": identifier, }) } diff --git a/internal/resources/app_definition/test_resources/create.tf b/internal/resources/app_definition/test_resources/create.tf new file mode 100644 index 0000000..54be05f --- /dev/null +++ b/internal/resources/app_definition/test_resources/create.tf @@ -0,0 +1,5 @@ +resource "contentful_app_definition" "{{ .identifier }}" { + name = "tf_test1" + use_bundle = true + locations = [{ location = "entry-field", "field_types" = [{ "type" = "Symbol" }] }] +} \ No newline at end of file diff --git a/internal/resources/app_definition/test_resources/update.tf b/internal/resources/app_definition/test_resources/update.tf new file mode 100644 index 0000000..227573d --- /dev/null +++ b/internal/resources/app_definition/test_resources/update.tf @@ -0,0 +1,5 @@ +resource "contentful_app_definition" "{{ .identifier }}" { + name = "tf_test1" + use_bundle = true + locations = [{ location = "entry-field", "field_types" = [{ "type" = "Symbol" }] }, { location = "dialog" }] +} \ No newline at end of file diff --git a/internal/resources/app_definition/test_resources/update_to_src.tf b/internal/resources/app_definition/test_resources/update_to_src.tf new file mode 100644 index 0000000..c2ccae7 --- /dev/null +++ b/internal/resources/app_definition/test_resources/update_to_src.tf @@ -0,0 +1,6 @@ +resource "contentful_app_definition" "{{ .identifier }}" { + name = "tf_test1" + use_bundle = false + locations = [{ location = "entry-field", "field_types" = [{ "type" = "Symbol" }] }] + src = "http://localhost" +} \ No newline at end of file diff --git a/internal/resources/app_installation/model.go b/internal/resources/app_installation/model.go new file mode 100644 index 0000000..539b10b --- /dev/null +++ b/internal/resources/app_installation/model.go @@ -0,0 +1,49 @@ +package app_installation + +import ( + "encoding/json" + "github.com/hashicorp/terraform-plugin-framework-jsontypes/jsontypes" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/labd/contentful-go" +) + +// AppInstallation is the main resource schema data +type AppInstallation struct { + ID types.String `tfsdk:"id"` + AppDefinitionID types.String `tfsdk:"app_definition_id"` + SpaceId types.String `tfsdk:"space_id"` + Environment types.String `tfsdk:"environment"` + Parameters jsontypes.Normalized `tfsdk:"parameters"` + AcceptedTerms []types.String `tfsdk:"accepted_terms"` +} + +func (a *AppInstallation) Draft() *contentful.AppInstallation { + + app := &contentful.AppInstallation{} + + parameters := make(map[string]any) + + a.Parameters.Unmarshal(¶meters) + + app.Parameters = parameters + + return app +} + +func (a *AppInstallation) Equal(n *contentful.AppInstallation) bool { + + data, _ := json.Marshal(n.Parameters) + + if a.Parameters.ValueString() != string(data) { + return false + } + + return true +} + +func (a *AppInstallation) Import(n *contentful.AppInstallation) { + a.AppDefinitionID = types.StringValue(n.Sys.AppDefinition.Sys.ID) + a.ID = types.StringValue(n.Sys.AppDefinition.Sys.ID) + data, _ := json.Marshal(n.Parameters) + a.Parameters = jsontypes.NewNormalizedValue(string(data)) +} diff --git a/internal/resources/app_installation/resource.go b/internal/resources/app_installation/resource.go new file mode 100644 index 0000000..182401f --- /dev/null +++ b/internal/resources/app_installation/resource.go @@ -0,0 +1,244 @@ +package app_installation + +import ( + "context" + _ "embed" + "errors" + "fmt" + "github.com/elliotchance/pie/v2" + "github.com/hashicorp/terraform-plugin-framework-jsontypes/jsontypes" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/labd/contentful-go" + "github.com/labd/terraform-provider-contentful/internal/utils" + "strings" +) + +// Ensure the implementation satisfies the expected interfaces. +var ( + _ resource.Resource = &appInstallationResource{} + _ resource.ResourceWithConfigure = &appInstallationResource{} + _ resource.ResourceWithImportState = &appInstallationResource{} +) + +func NewAppInstallationResource() resource.Resource { + return &appInstallationResource{} +} + +// appInstallationResource is the resource implementation. +type appInstallationResource struct { + client *contentful.Client + organizationId string +} + +func (e *appInstallationResource) Metadata(_ context.Context, request resource.MetadataRequest, response *resource.MetadataResponse) { + response.TypeName = request.ProviderTypeName + "_app_installation" +} + +func (e *appInstallationResource) Schema(_ context.Context, _ resource.SchemaRequest, response *resource.SchemaResponse) { + response.Schema = schema.Schema{ + Description: "Todo for explaining app installation", + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + Computed: true, + }, + "app_definition_id": schema.StringAttribute{ + Required: true, + Description: "app definition id", + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + }, + "space_id": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + Description: "space id", + }, + "environment": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + }, + "parameters": schema.StringAttribute{ + CustomType: jsontypes.NormalizedType{}, + Description: "Parameters needed for the installation of the app in the given space, like credentials or other configuration parameters", + Required: true, + }, + "accepted_terms": schema.ListAttribute{ + Optional: true, + Description: "List of needed terms to accept to install the app", + ElementType: types.StringType, + }, + }, + } +} + +func (e *appInstallationResource) Configure(_ context.Context, request resource.ConfigureRequest, _ *resource.ConfigureResponse) { + if request.ProviderData == nil { + return + } + + data := request.ProviderData.(utils.ProviderData) + e.client = data.Client + e.organizationId = data.OrganizationId + +} + +func (e *appInstallationResource) Create(ctx context.Context, request resource.CreateRequest, response *resource.CreateResponse) { + var plan *AppInstallation + response.Diagnostics.Append(request.Plan.Get(ctx, &plan)...) + if response.Diagnostics.HasError() { + return + } + + draft := plan.Draft() + + terms := pie.Map(plan.AcceptedTerms, func(t types.String) string { + return t.ValueString() + }) + + if err := e.client.AppInstallations.Upsert(plan.SpaceId.ValueString(), plan.AppDefinitionID.ValueString(), draft, plan.Environment.ValueString(), terms); err != nil { + var errorResponse contentful.ErrorResponse + if errors.As(err, &errorResponse) { + if errorResponse.Error() == "Forbidden" { + response.Diagnostics.AddError("Error creating app_installation", fmt.Sprintf("%s: %s", errorResponse.Error(), errorResponse.Details.Reasons)) + } + } + + response.Diagnostics.AddError("Error creating app_installation", err.Error()) + return + } + + plan.ID = plan.AppDefinitionID + + // Set state to fully populated data + response.Diagnostics.Append(response.State.Set(ctx, plan)...) + if response.Diagnostics.HasError() { + return + } +} + +func (e *appInstallationResource) Read(ctx context.Context, request resource.ReadRequest, response *resource.ReadResponse) { + // Get current state + var state *AppInstallation + diags := request.State.Get(ctx, &state) + response.Diagnostics.Append(diags...) + if response.Diagnostics.HasError() { + return + } + + e.doRead(ctx, state, &response.State, &response.Diagnostics) +} + +func (e *appInstallationResource) doRead(ctx context.Context, app *AppInstallation, state *tfsdk.State, d *diag.Diagnostics) { + + appDefinition, err := e.getAppInstallation(app) + if err != nil { + d.AddError( + "Error reading app installation", + "Could not retrieve app installation, unexpected error: "+err.Error(), + ) + return + } + + app.Import(appDefinition) + + // Set refreshed state + d.Append(state.Set(ctx, &app)...) + if d.HasError() { + return + } +} + +func (e *appInstallationResource) Update(ctx context.Context, request resource.UpdateRequest, response *resource.UpdateResponse) { + // Retrieve values from plan + var plan *AppInstallation + diags := request.Plan.Get(ctx, &plan) + response.Diagnostics.Append(diags...) + if response.Diagnostics.HasError() { + return + } + + // Get current state + var state *AppInstallation + diags = request.State.Get(ctx, &state) + response.Diagnostics.Append(diags...) + if response.Diagnostics.HasError() { + return + } + + appDefinition, err := e.getAppInstallation(plan) + if err != nil { + response.Diagnostics.AddError( + "Error reading app installation", + "Could not retrieve app installation, unexpected error: "+err.Error(), + ) + return + } + + if !plan.Equal(appDefinition) { + + draft := plan.Draft() + + terms := pie.Map(plan.AcceptedTerms, func(t types.String) string { + return t.ValueString() + }) + + if err = e.client.AppInstallations.Upsert(plan.SpaceId.ValueString(), plan.AppDefinitionID.ValueString(), draft, plan.Environment.ValueString(), terms); err != nil { + response.Diagnostics.AddError( + "Error updating app installation", + "Could not update app installation, unexpected error: "+err.Error(), + ) + return + } + } + + e.doRead(ctx, plan, &response.State, &response.Diagnostics) +} + +func (e *appInstallationResource) Delete(ctx context.Context, request resource.DeleteRequest, response *resource.DeleteResponse) { + // Get current state + var state *AppInstallation + response.Diagnostics.Append(request.State.Get(ctx, &state)...) + + if err := e.client.AppInstallations.Delete(state.SpaceId.ValueString(), state.AppDefinitionID.ValueString(), state.Environment.ValueString()); err != nil { + response.Diagnostics.AddError( + "Error deleting app_installation", + "Could not delete app_installation, unexpected error: "+err.Error(), + ) + return + } + +} + +func (e *appInstallationResource) ImportState(ctx context.Context, request resource.ImportStateRequest, response *resource.ImportStateResponse) { + idParts := strings.SplitN(request.ID, ":", 3) + + if len(idParts) != 3 || idParts[0] == "" || idParts[1] == "" || idParts[2] == "" { + response.Diagnostics.AddError( + "Unexpected Import Identifier", + fmt.Sprintf("Expected import identifier with format: appDefinitionID:env:spaceId. Got: %q", request.ID), + ) + return + } + + futureState := &AppInstallation{ + AppDefinitionID: types.StringValue(idParts[0]), + SpaceId: types.StringValue(idParts[2]), + Environment: types.StringValue(idParts[1]), + } + + e.doRead(ctx, futureState, &response.State, &response.Diagnostics) +} + +func (e *appInstallationResource) getAppInstallation(app *AppInstallation) (*contentful.AppInstallation, error) { + return e.client.AppInstallations.Get(app.SpaceId.ValueString(), app.AppDefinitionID.ValueString(), app.Environment.ValueString()) +} diff --git a/internal/resources/app_installation/resource_test.go b/internal/resources/app_installation/resource_test.go new file mode 100644 index 0000000..cb007ad --- /dev/null +++ b/internal/resources/app_installation/resource_test.go @@ -0,0 +1,124 @@ +package app_installation_test + +import ( + "errors" + "fmt" + "github.com/hashicorp/terraform-plugin-framework/providerserver" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" + "github.com/labd/contentful-go" + "github.com/labd/terraform-provider-contentful/internal/acctest" + "github.com/labd/terraform-provider-contentful/internal/provider" + "github.com/labd/terraform-provider-contentful/internal/utils" + "github.com/stretchr/testify/assert" + "os" + "testing" +) + +type assertFunc func(*testing.T, *contentful.AppInstallation) + +func TestAppInstallation_Create(t *testing.T) { + resourceName := "contentful_app_installation.acctest_app_installation" + // merge app + appInstallationId := "cQeaauOu1yUCYVhQ00atE" + //graphql playground + otherId := "66frtrAqmWSowDJzQNDiD" + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.TestAccPreCheck(t) }, + CheckDestroy: testAccCheckContentfulAppInstallationDestroy, + ProtoV6ProviderFactories: map[string]func() (tfprotov6.ProviderServer, error){ + "contentful": providerserver.NewProtocol6WithError(provider.New("test", true)), + }, + Steps: []resource.TestStep{ + { + Config: testAppInstallation("acctest_app_installation", os.Getenv("CONTENTFUL_SPACE_ID"), "master", appInstallationId), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "app_definition_id", appInstallationId), + testAccCheckContentfulAppInstallationExists(t, resourceName, func(t *testing.T, appInstallation *contentful.AppInstallation) { + assert.IsType(t, map[string]any{}, appInstallation.Parameters) + assert.Len(t, appInstallation.Parameters, 0) + assert.EqualValues(t, appInstallationId, appInstallation.Sys.AppDefinition.Sys.ID) + }), + ), + }, + { + Config: testAppInstallationWithParameter("acctest_app_installation_2", os.Getenv("CONTENTFUL_SPACE_ID"), "master", otherId), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("contentful_app_installation.acctest_app_installation_2", "app_definition_id", otherId), + testAccCheckContentfulAppInstallationExists(t, "contentful_app_installation.acctest_app_installation_2", func(t *testing.T, appInstallation *contentful.AppInstallation) { + assert.IsType(t, map[string]any{}, appInstallation.Parameters) + assert.Len(t, appInstallation.Parameters, 1) + assert.EqualValues(t, "not-working-ever", appInstallation.Parameters["cpaToken"]) + assert.EqualValues(t, otherId, appInstallation.Sys.AppDefinition.Sys.ID) + }), + ), + }, + }, + }) +} + +func getAppInstallationFromState(s *terraform.State, resourceName string) (*contentful.AppInstallation, error) { + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return nil, fmt.Errorf("app installation not found") + } + + if rs.Primary.ID == "" { + return nil, fmt.Errorf("no app installation ID found") + } + + client := acctest.GetClient() + + return client.AppInstallations.Get(os.Getenv("CONTENTFUL_SPACE_ID"), rs.Primary.ID, "master") +} + +func testAccCheckContentfulAppInstallationExists(t *testing.T, resourceName string, assertFunc assertFunc) resource.TestCheckFunc { + return func(s *terraform.State) error { + result, err := getAppInstallationFromState(s, resourceName) + if err != nil { + return err + } + + assertFunc(t, result) + return nil + } +} + +func testAccCheckContentfulAppInstallationDestroy(s *terraform.State) error { + client := acctest.GetClient() + + for _, rs := range s.RootModule().Resources { + if rs.Type != "contentful_app_installation" { + continue + } + + _, err := client.AppInstallations.Get(os.Getenv("CONTENTFUL_ORGANIZATION_ID"), rs.Primary.ID, "master") + var notFoundError contentful.NotFoundError + if errors.As(err, ¬FoundError) { + return nil + } + + return fmt.Errorf("app installation still exists with id: %s", rs.Primary.ID) + } + + return nil +} + +func testAppInstallation(identifier string, spaceId string, environment string, appDefinitionId string) string { + return utils.HCLTemplateFromPath("test_resources/without_terms.tf", map[string]any{ + "identifier": identifier, + "spaceId": spaceId, + "environment": environment, + "appDefinitionId": appDefinitionId, + }) +} + +func testAppInstallationWithParameter(identifier string, spaceId string, environment string, appDefinitionId string) string { + return utils.HCLTemplateFromPath("test_resources/with_terms.tf", map[string]any{ + "identifier": identifier, + "spaceId": spaceId, + "environment": environment, + "appDefinitionId": appDefinitionId, + }) +} diff --git a/internal/resources/app_installation/test_resources/with_terms.tf b/internal/resources/app_installation/test_resources/with_terms.tf new file mode 100644 index 0000000..05c56ec --- /dev/null +++ b/internal/resources/app_installation/test_resources/with_terms.tf @@ -0,0 +1,14 @@ +resource "contentful_app_installation" "{{ .identifier }}" { + + space_id = "{{ .spaceId }}" + environment = "{{ .environment }}" + + app_definition_id = "{{ .appDefinitionId }}" + + parameters = jsonencode({ + cpaToken = "not-working-ever" + }) + + accepted_terms = ["i-accept-end-user-license-agreement", "i-accept-marketplace-terms-of-service", "i-accept-privacy-policy"] + +} \ No newline at end of file diff --git a/internal/resources/app_installation/test_resources/without_terms.tf b/internal/resources/app_installation/test_resources/without_terms.tf new file mode 100644 index 0000000..776d44b --- /dev/null +++ b/internal/resources/app_installation/test_resources/without_terms.tf @@ -0,0 +1,10 @@ +resource "contentful_app_installation" "{{ .identifier }}" { + + space_id = "{{ .spaceId }}" + environment = "{{ .environment }}" + + app_definition_id = "{{ .appDefinitionId }}" + + parameters = jsonencode({}) + +} \ No newline at end of file diff --git a/internal/resources/contenttype/model.go b/internal/resources/contenttype/model.go index cca53cb..3d2d869 100644 --- a/internal/resources/contenttype/model.go +++ b/internal/resources/contenttype/model.go @@ -1,8 +1,10 @@ package contenttype import ( + "encoding/json" "fmt" "github.com/elliotchance/pie/v2" + "github.com/hashicorp/terraform-plugin-framework-jsontypes/jsontypes" "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/types" "github.com/labd/contentful-go" @@ -22,6 +24,14 @@ type ContentType struct { VersionControls types.Int64 `tfsdk:"version_controls"` Fields []Field `tfsdk:"fields"` ManageFieldControls types.Bool `tfsdk:"manage_field_controls"` + Sidebar []Sidebar `tfsdk:"sidebar"` +} + +type Sidebar struct { + WidgetId types.String `tfsdk:"widget_id"` + WidgetNamespace types.String `tfsdk:"widget_namespace"` + Settings jsontypes.Normalized `tfsdk:"settings"` + Disabled types.Bool `tfsdk:"disabled"` } type Field struct { @@ -45,23 +55,23 @@ type DefaultValue struct { } func (d *DefaultValue) Draft() map[string]any { - var default_values = map[string]any{} + var defaultValues = map[string]any{} if !d.String.IsNull() && !d.String.IsUnknown() { for k, v := range d.String.Elements() { - default_values[k] = v.(types.String).ValueString() + defaultValues[k] = v.(types.String).ValueString() } } if !d.Bool.IsNull() && !d.Bool.IsUnknown() { for k, v := range d.Bool.Elements() { - default_values[k] = v.(types.Bool).ValueBool() + defaultValues[k] = v.(types.Bool).ValueBool() } } - return default_values + return defaultValues } type Control struct { @@ -149,7 +159,7 @@ func (v Validation) Draft() contentful.FieldValidation { if len(v.In) > 0 { return contentful.FieldValidationPredefinedValues{ - In: pie.Map(v.In, func(t types.String) interface{} { + In: pie.Map(v.In, func(t types.String) any { return t.ValueString() }), } @@ -522,9 +532,11 @@ func (c *ContentType) Import(n *contentful.ContentType, e *contentful.EditorInte var fields []Field var controls []contentful.Controls - + var sidebar []contentful.Sidebar + c.VersionControls = types.Int64Value(0) if e != nil { controls = e.Controls + sidebar = e.SideBar c.VersionControls = types.Int64Value(int64(e.Sys.Version)) } @@ -537,6 +549,22 @@ func (c *ContentType) Import(n *contentful.ContentType, e *contentful.EditorInte fields = append(fields, *field) } + c.Sidebar = pie.Map(sidebar, func(t contentful.Sidebar) Sidebar { + + settings := jsontypes.NewNormalizedValue("{}") + + if t.Settings != nil { + data, _ := json.Marshal(t.Settings) + settings = jsontypes.NewNormalizedValue(string(data)) + } + return Sidebar{ + WidgetId: types.StringValue(t.WidgetID), + WidgetNamespace: types.StringValue(t.WidgetNameSpace), + Settings: settings, + Disabled: types.BoolValue(t.Disabled), + } + }) + c.Fields = fields return nil @@ -583,13 +611,13 @@ func (c *ContentType) Equal(n *contentful.ContentType) bool { return true } -func (c *ContentType) EqualControls(n []contentful.Controls) bool { +func (c *ContentType) EqualEditorInterface(n *contentful.EditorInterface) bool { - if len(c.Fields) != len(n) { + if len(c.Fields) != len(n.Controls) { return false } - filteredControls := pie.Filter(n, func(c contentful.Controls) bool { + filteredControls := pie.Filter(n.Controls, func(c contentful.Controls) bool { return c.WidgetID != nil || c.WidgetNameSpace != nil || c.Settings != nil }) @@ -628,11 +656,52 @@ func (c *ContentType) EqualControls(n []contentful.Controls) bool { } } + if len(c.Sidebar) != len(n.SideBar) { + return false + } + + for idxOrg, s := range c.Sidebar { + idx := pie.FindFirstUsing(n.SideBar, func(t contentful.Sidebar) bool { + return t.WidgetID == s.WidgetId.ValueString() + }) + + if idx == -1 { + return false + } + + // field was moved, it is the same as before but different position + if idxOrg != idx { + return false + } + + sidebar := n.SideBar[idx] + + if sidebar.Disabled != s.Disabled.ValueBool() { + return false + } + + if sidebar.WidgetID != s.WidgetId.ValueString() { + return false + } + + if sidebar.WidgetNameSpace != s.WidgetNamespace.ValueString() { + return false + } + + a := make(map[string]string) + + s.Settings.Unmarshal(a) + + if !reflect.DeepEqual(sidebar.Settings, a) { + return false + } + } + return true } -func (c *ContentType) DraftControls() []contentful.Controls { - return pie.Map(c.Fields, func(field Field) contentful.Controls { +func (c *ContentType) DraftEditorInterface(n *contentful.EditorInterface) { + n.Controls = pie.Map(c.Fields, func(field Field) contentful.Controls { control := contentful.Controls{ FieldID: field.Id.ValueString(), @@ -650,6 +719,24 @@ func (c *ContentType) DraftControls() []contentful.Controls { return control }) + + n.SideBar = pie.Map(c.Sidebar, func(t Sidebar) contentful.Sidebar { + + sidebar := contentful.Sidebar{ + WidgetNameSpace: t.WidgetNamespace.ValueString(), + WidgetID: t.WidgetId.ValueString(), + Disabled: t.Disabled.ValueBool(), + } + + if !sidebar.Disabled { + settings := make(map[string]string) + + t.Settings.Unmarshal(settings) + sidebar.Settings = settings + } + + return sidebar + }) } func getValidations(contentfulValidations []contentful.FieldValidation) ([]Validation, error) { @@ -765,5 +852,5 @@ func getValidation(cfVal contentful.FieldValidation) (*Validation, error) { }, nil } - return nil, fmt.Errorf("Unsupported validation used, %s. Please implement", reflect.TypeOf(cfVal).String()) + return nil, fmt.Errorf("unsupported validation used, %s. Please implement", reflect.TypeOf(cfVal).String()) } diff --git a/internal/resources/contenttype/resource.go b/internal/resources/contenttype/resource.go index b110e47..ec82bec 100644 --- a/internal/resources/contenttype/resource.go +++ b/internal/resources/contenttype/resource.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "github.com/elliotchance/pie/v2" + "github.com/hashicorp/terraform-plugin-framework-jsontypes/jsontypes" "github.com/hashicorp/terraform-plugin-framework-validators/listvalidator" "github.com/hashicorp/terraform-plugin-framework-validators/objectvalidator" "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" @@ -335,6 +336,35 @@ func (e *contentTypeResource) Schema(ctx context.Context, request resource.Schem }, }, }, + + "sidebar": schema.ListNestedAttribute{ + Optional: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "disabled": schema.BoolAttribute{ + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Bool{ + custommodifier.BoolDefault(false), + }, + }, + "widget_id": schema.StringAttribute{ + Required: true, + }, + "widget_namespace": schema.StringAttribute{ + Required: true, + }, + "settings": schema.StringAttribute{ + CustomType: jsontypes.NormalizedType{}, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.String{ + custommodifier.StringDefault("{}"), + }, + }, + }, + }, + }, }, } } @@ -427,10 +457,10 @@ func (e *contentTypeResource) doRead(ctx context.Context, contentType *ContentTy return } - var controls *contentful.EditorInterface + var editorInterface *contentful.EditorInterface if contentType.ManageFieldControls.ValueBool() { - controls, err = e.getContentTypeControls(contentType) + editorInterface, err = e.getEditorInterface(contentType) if err != nil { d.AddError( "Error reading contenttype", @@ -440,19 +470,20 @@ func (e *contentTypeResource) doRead(ctx context.Context, contentType *ContentTy } if u, ok := ctx.Value(OnlyControlVersion).(bool); ok && u { - contentType.VersionControls = types.Int64Value(int64(controls.Sys.Version)) + contentType.VersionControls = types.Int64Value(int64(editorInterface.Sys.Version)) - draftControls := contentType.DraftControls() + ei := &contentful.EditorInterface{} + contentType.DraftEditorInterface(ei) // remove all controls which are not in the plan for an easier import - controls.Controls = pie.Filter(controls.Controls, func(c contentful.Controls) bool { - return pie.Any(draftControls, func(value contentful.Controls) bool { + editorInterface.Controls = pie.Filter(editorInterface.Controls, func(c contentful.Controls) bool { + return pie.Any(ei.Controls, func(value contentful.Controls) bool { return value.FieldID == c.FieldID && value.WidgetID != nil && reflect.DeepEqual(value.WidgetID, c.WidgetID) }) }) } } - err = contentType.Import(contentfulContentType, controls) + err = contentType.Import(contentfulContentType, editorInterface) if err != nil { d.AddError( @@ -555,38 +586,38 @@ func (e *contentTypeResource) Update(ctx context.Context, request resource.Updat } } - ctxControls := e.updateControls(ctx, state, plan, &response.Diagnostics) + ctxControls := e.updateEditorInterface(ctx, state, plan, &response.Diagnostics) e.doRead(ctxControls, plan, &response.State, &response.Diagnostics) } -func (e *contentTypeResource) updateControls(ctx context.Context, state *ContentType, plan *ContentType, d *diag.Diagnostics) context.Context { +func (e *contentTypeResource) updateEditorInterface(ctx context.Context, state *ContentType, plan *ContentType, d *diag.Diagnostics) context.Context { if plan.ManageFieldControls.ValueBool() { - // first import of controls to the state just get the controls version + // first import of editorInterface to the state just get the editorInterface version if state.VersionControls.IsNull() { return context.WithValue(ctx, OnlyControlVersion, true) } - controls, err := e.getContentTypeControls(plan) + editorInterface, err := e.getEditorInterface(plan) if err != nil { d.AddError( "Error reading contenttype", - "Could not retrieve contenttype controls, unexpected error: "+err.Error(), + "Could not retrieve contenttype editorInterface, unexpected error: "+err.Error(), ) return ctx } - if !plan.EqualControls(controls.Controls) { + if !plan.EqualEditorInterface(editorInterface) { - controls.Controls = plan.DraftControls() + plan.DraftEditorInterface(editorInterface) if !plan.Environment.IsUnknown() && !plan.Environment.IsNull() { e.client.SetEnvironment(plan.Environment.ValueString()) } - if err = e.client.EditorInterfaces.Update(plan.SpaceId.ValueString(), plan.ID.ValueString(), controls); err != nil { + if err = e.client.EditorInterfaces.Update(plan.SpaceId.ValueString(), plan.ID.ValueString(), editorInterface); err != nil { d.AddError( - "Error updating contenttype controls", - "Could not update contenttype controls, unexpected error: "+err.Error(), + "Error updating contenttype editorInterface", + "Could not update contenttype editorInterface, unexpected error: "+err.Error(), ) return ctx @@ -721,7 +752,7 @@ func (e *contentTypeResource) getContentType(editor *ContentType) (*contentful.C } } -func (e *contentTypeResource) getContentTypeControls(editor *ContentType) (*contentful.EditorInterface, error) { +func (e *contentTypeResource) getEditorInterface(editor *ContentType) (*contentful.EditorInterface, error) { if !editor.Environment.IsUnknown() && !editor.Environment.IsNull() { env := &contentful.Environment{Sys: &contentful.Sys{ diff --git a/internal/resources/contenttype/resource_test.go b/internal/resources/contenttype/resource_test.go index 0122a93..5eee94e 100644 --- a/internal/resources/contenttype/resource_test.go +++ b/internal/resources/contenttype/resource_test.go @@ -11,11 +11,15 @@ import ( "github.com/labd/terraform-provider-contentful/internal/acctest" "github.com/labd/terraform-provider-contentful/internal/provider" "github.com/labd/terraform-provider-contentful/internal/utils" + "github.com/stretchr/testify/assert" "os" "testing" ) +type assertFunc func(*testing.T, *contentful.ContentType) +type assertEditorInterfaceFunc func(*testing.T, *contentful.EditorInterface) + func TestContentTypeResource_Create(t *testing.T) { resourceName := "contentful_contenttype.acctest_content_type" linkedResourceName := "contentful_contenttype.linked_content_type" @@ -33,7 +37,40 @@ func TestContentTypeResource_Create(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "id", "tf_test1"), resource.TestCheckResourceAttr(resourceName, "version", "2"), resource.TestCheckResourceAttr(resourceName, "version_controls", "0"), - //todo check in contentful directly if the type looks like this + testAccCheckContentfulContentTypeExists(t, resourceName, func(t *testing.T, contentType *contentful.ContentType) { + assert.EqualValues(t, "tf_test1", contentType.Name) + assert.Equal(t, 2, contentType.Sys.Version) + assert.EqualValues(t, "tf_test1", contentType.Sys.ID) + assert.EqualValues(t, "none", *contentType.Description) + assert.EqualValues(t, "field1", contentType.DisplayField) + assert.Len(t, contentType.Fields, 2) + assert.Equal(t, &contentful.Field{ + ID: "field1", + Name: "Field 1 name change", + Type: "Text", + LinkType: "", + Items: nil, + Required: true, + Localized: false, + Disabled: false, + Omitted: false, + Validations: nil, + DefaultValue: nil, + }, contentType.Fields[0]) + assert.Equal(t, &contentful.Field{ + ID: "field3", + Name: "Field 3 new field", + Type: "Integer", + LinkType: "", + Items: nil, + Required: true, + Localized: false, + Disabled: false, + Omitted: false, + Validations: nil, + DefaultValue: nil, + }, contentType.Fields[1]) + }), ), }, { @@ -42,7 +79,34 @@ func TestContentTypeResource_Create(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "name", "tf_test1"), resource.TestCheckResourceAttr(resourceName, "version", "4"), resource.TestCheckResourceAttr(resourceName, "version_controls", "0"), - //todo check in contentful directly if the type looks like this + testAccCheckContentfulContentTypeExists(t, resourceName, func(t *testing.T, contentType *contentful.ContentType) { + assert.EqualValues(t, "tf_test1", contentType.Name) + assert.Equal(t, 4, contentType.Sys.Version) + assert.EqualValues(t, "tf_test1", contentType.Sys.ID) + assert.EqualValues(t, "Terraform Acc Test Content Type description change", *contentType.Description) + assert.EqualValues(t, "field1", contentType.DisplayField) + assert.Len(t, contentType.Fields, 2) + assert.Equal(t, &contentful.Field{ + ID: "field1", + Name: "Field 1 name change", + Type: "Text", + LinkType: "", + Required: true, + Localized: false, + Disabled: false, + Omitted: false, + }, contentType.Fields[1]) + assert.Equal(t, &contentful.Field{ + ID: "field3", + Name: "Field 3 new field", + Type: "Integer", + LinkType: "", + Required: true, + Localized: false, + Disabled: false, + Omitted: false, + }, contentType.Fields[0]) + }), ), }, { @@ -50,15 +114,93 @@ func TestContentTypeResource_Create(t *testing.T) { Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(resourceName, "name", "tf_test1"), resource.TestCheckResourceAttr(resourceName, "version", "6"), - resource.TestCheckResourceAttr(resourceName, "version_controls", "2"), - //todo check in contentful directly if the type looks like this + resource.TestCheckResourceAttr(resourceName, "version_controls", "4"), + testAccCheckContentfulContentTypeExists(t, resourceName, func(t *testing.T, contentType *contentful.ContentType) { + assert.EqualValues(t, "tf_test1", contentType.Name) + assert.Equal(t, 6, contentType.Sys.Version) + assert.EqualValues(t, "tf_test1", contentType.Sys.ID) + assert.EqualValues(t, "Terraform Acc Test Content Type description change", *contentType.Description) + assert.EqualValues(t, "field1", contentType.DisplayField) + assert.Len(t, contentType.Fields, 2) + assert.Equal(t, &contentful.Field{ + ID: "field1", + Name: "Field 1 name change", + Type: "Text", + LinkType: "", + Required: true, + Localized: false, + Disabled: false, + Omitted: false, + }, contentType.Fields[0]) + assert.Equal(t, &contentful.Field{ + ID: "field3", + Name: "Field 3 new field", + Type: "Integer", + LinkType: "", + Required: true, + Localized: false, + Disabled: false, + Omitted: false, + }, contentType.Fields[1]) + }), + testAccCheckEditorInterfaceExists(t, "tf_test1", func(t *testing.T, editorInterface *contentful.EditorInterface) { + assert.Len(t, editorInterface.Controls, 2) + assert.Equal(t, contentful.Controls{ + FieldID: "field1", + }, editorInterface.Controls[0]) + assert.Equal(t, contentful.Controls{ + FieldID: "field3", + WidgetNameSpace: toPointer("builtin"), + WidgetID: toPointer("numberEditor"), + Settings: &contentful.Settings{ + BulkEditing: toPointer(true), + HelpText: toPointer("blabla"), + }, + }, editorInterface.Controls[1]) + }), ), }, { Config: testContentTypeLinkConfig("acctest_content_type", os.Getenv("CONTENTFUL_SPACE_ID"), "linked_content_type"), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(linkedResourceName, "name", "tf_linked"), - //todo check in contentful directly if the type looks like this + testAccCheckContentfulContentTypeExists(t, linkedResourceName, func(t *testing.T, contentType *contentful.ContentType) { + assert.EqualValues(t, "tf_linked", contentType.Name) + assert.Equal(t, 2, contentType.Sys.Version) + assert.EqualValues(t, "tf_linked", contentType.Sys.ID) + assert.EqualValues(t, "Terraform Acc Test Content Type with links", *contentType.Description) + assert.EqualValues(t, "asset_field", contentType.DisplayField) + assert.Len(t, contentType.Fields, 2) + assert.Equal(t, &contentful.Field{ + ID: "asset_field", + Name: "Asset Field", + Type: "Array", + LinkType: "", + Items: &contentful.FieldTypeArrayItem{ + Type: "Link", + LinkType: toPointer("Asset"), + }, + Required: true, + Localized: false, + Disabled: false, + Omitted: false, + }, contentType.Fields[0]) + assert.Equal(t, &contentful.Field{ + ID: "entry_link_field", + Name: "Entry Link Field", + Type: "Link", + LinkType: "Entry", + Required: false, + Localized: false, + Disabled: false, + Omitted: false, + Validations: []contentful.FieldValidation{ + contentful.FieldValidationLink{ + LinkContentType: []string{"tf_test1"}, + }, + }, + }, contentType.Fields[1]) + }), ), }, { @@ -66,12 +208,83 @@ func TestContentTypeResource_Create(t *testing.T) { Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(resourceName, "name", "tf_test1"), resource.TestCheckResourceAttr(resourceName, "id", "tf_test2"), - //todo check in contentful directly if the type looks like this + testAccCheckContentfulContentTypeExists(t, resourceName, func(t *testing.T, contentType *contentful.ContentType) { + assert.EqualValues(t, "tf_test1", contentType.Name) + assert.Equal(t, 2, contentType.Sys.Version) + assert.EqualValues(t, "tf_test2", contentType.Sys.ID) + assert.EqualValues(t, "Terraform Acc Test Content Type description change", *contentType.Description) + assert.EqualValues(t, "field1", contentType.DisplayField) + assert.Len(t, contentType.Fields, 2) + assert.Equal(t, &contentful.Field{ + ID: "field1", + Name: "Field 1 name change", + Type: "Text", + LinkType: "", + Required: true, + Localized: false, + Disabled: false, + Omitted: false, + }, contentType.Fields[0]) + assert.Equal(t, &contentful.Field{ + ID: "field3", + Name: "Field 3 new field", + Type: "Integer", + LinkType: "", + Required: true, + Localized: false, + Disabled: false, + Omitted: false, + }, contentType.Fields[1]) + }), ), }, }, }) } +func getContentTypeFromState(s *terraform.State, resourceName string) (*contentful.ContentType, error) { + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return nil, fmt.Errorf("content type not found") + } + + if rs.Primary.ID == "" { + return nil, fmt.Errorf("no content type ID found") + } + + client := acctest.GetClient() + + return client.ContentTypes.Get(os.Getenv("CONTENTFUL_SPACE_ID"), rs.Primary.ID) +} + +func getEditorInterfaceFromState(id string) (*contentful.EditorInterface, error) { + client := acctest.GetClient() + + return client.EditorInterfaces.Get(os.Getenv("CONTENTFUL_SPACE_ID"), id) +} + +func testAccCheckContentfulContentTypeExists(t *testing.T, resourceName string, assertFunc assertFunc) resource.TestCheckFunc { + return func(s *terraform.State) error { + result, err := getContentTypeFromState(s, resourceName) + if err != nil { + return err + } + + assertFunc(t, result) + return nil + } +} + +func testAccCheckEditorInterfaceExists(t *testing.T, id string, assertFunc assertEditorInterfaceFunc) resource.TestCheckFunc { + return func(s *terraform.State) error { + result, err := getEditorInterfaceFromState(id) + if err != nil { + return err + } + + assertFunc(t, result) + return nil + } +} func testAccCheckContentfulContentTypeDestroy(s *terraform.State) (err error) { client := acctest.GetClient() @@ -99,166 +312,46 @@ func testAccCheckContentfulContentTypeDestroy(s *terraform.State) (err error) { } func testContentType(identifier string, spaceId string) string { - return utils.HCLTemplate(` - resource "contentful_contenttype" "{{ .identifier }}" { - space_id = "{{ .spaceId }}" - name = "tf_test1" - description = "Terraform Acc Test Content Type description change" - display_field = "field1" - fields = [{ - id = "field1" - name = "Field 1 name change" - required = true - type = "Text" - }, { - id = "field3" - name = "Field 3 new field" - required = true - type = "Integer" - }] -}`, map[string]any{ - "identifier": identifier, - "spaceId": spaceId, + return utils.HCLTemplateFromPath("test_resources/create.tf", map[string]any{ + "identifier": identifier, + "spaceId": spaceId, + "id_definition": "", + "desc": "none", }) } func testContentTypeWithId(identifier string, spaceId string) string { - return utils.HCLTemplate(` - resource "contentful_contenttype" "{{ .identifier }}" { - space_id = "{{ .spaceId }}" - id = "tf_test2" - name = "tf_test1" - description = "Terraform Acc Test Content Type description change" - display_field = "field1" - fields = [{ - id = "field1" - name = "Field 1 name change" - required = true - type = "Text" - }, { - id = "field3" - name = "Field 3 new field" - required = true - type = "Integer" - }] -}`, map[string]any{ - "identifier": identifier, - "spaceId": spaceId, + return utils.HCLTemplateFromPath("test_resources/create.tf", map[string]any{ + "identifier": identifier, + "spaceId": spaceId, + "id_definition": "id = \"tf_test2\"", + "desc": "Terraform Acc Test Content Type description change", }) } func testContentTypeUpdateWithDifferentOrderOfFields(identifier string, spaceId string) string { - return utils.HCLTemplate(` - resource "contentful_contenttype" "{{ .identifier }}" { - space_id = "{{ .spaceId }}" - name = "tf_test1" - description = "Terraform Acc Test Content Type description change" - display_field = "field1" - fields = [{ - id = "field3" - name = "Field 3 new field" - required = true - type = "Integer" - },{ - id = "field1" - name = "Field 1 name change" - required = true - type = "Text" - } ] -}`, map[string]any{ + return utils.HCLTemplateFromPath("test_resources/changed_order.tf", map[string]any{ "identifier": identifier, "spaceId": spaceId, }) } func testContentTypeUpdate(identifier string, spaceId string) string { - return utils.HCLTemplate(` - resource "contentful_contenttype" "{{ .identifier }}" { - space_id = "{{ .spaceId }}" - name = "tf_test1" - description = "Terraform Acc Test Content Type description change" - display_field = "field1" -manage_field_controls = true - fields = [{ - id = "field1" - name = "Field 1 name change" - required = true - type = "Text" - }, { - id = "field3" - name = "Field 3 new field" - required = true - type = "Integer" - control = { - widget_id = "numberEditor" - widget_namespace = "builtin" - settings = { - help_text = "blabla" - bulk_editing = true - } - } - }] -}`, map[string]any{ + return utils.HCLTemplateFromPath("test_resources/update.tf", map[string]any{ "identifier": identifier, "spaceId": spaceId, }) } func testContentTypeLinkConfig(identifier string, spaceId string, linkIdentifier string) string { - return utils.HCLTemplate(`resource "contentful_contenttype" "{{ .identifier }}" { - space_id = "{{ .spaceId }}" - name = "tf_test1" - description = "Terraform Acc Test Content Type description change" - display_field = "field1" -manage_field_controls = true - fields = [{ - id = "field1" - name = "Field 1 name change" - required = true - type = "Text" - }, { - id = "field3" - name = "Field 3 new field" - required = true - type = "Integer" - control = { - widget_id = "numberEditor" - widget_namespace = "builtin" - settings = { - help_text = "blabla" - bulk_editing = false - } - } - }] -} - -resource "contentful_contenttype" "{{ .linkIdentifier }}" { - space_id = "{{ .spaceId }}" - name = "tf_linked" - description = "Terraform Acc Test Content Type with links" - display_field = "asset_field" - fields =[{ - id = "asset_field" - name = "Asset Field" - type = "Array" - items = { - type = "Link" - link_type = "Asset" - } - required = true - },{ - id = "entry_link_field" - name = "Entry Link Field" - type = "Link" - link_type = "Entry" - validations = [{ - link_content_type = [contentful_contenttype.{{ .identifier }}.id ] - }] - }] -} -`, map[string]any{ + return utils.HCLTemplateFromPath("test_resources/link_config.tf", map[string]any{ "identifier": identifier, "linkIdentifier": linkIdentifier, "spaceId": spaceId, }) + +} + +func toPointer[T string | bool](value T) *T { + return &value } diff --git a/internal/resources/contenttype/test_resources/changed_order.tf b/internal/resources/contenttype/test_resources/changed_order.tf new file mode 100644 index 0000000..4b3af8a --- /dev/null +++ b/internal/resources/contenttype/test_resources/changed_order.tf @@ -0,0 +1,17 @@ +resource "contentful_contenttype" "{{ .identifier }}" { + space_id = "{{ .spaceId }}" + name = "tf_test1" + description = "Terraform Acc Test Content Type description change" + display_field = "field1" + fields = [{ + id = "field3" + name = "Field 3 new field" + required = true + type = "Integer" + }, { + id = "field1" + name = "Field 1 name change" + required = true + type = "Text" + }] +} \ No newline at end of file diff --git a/internal/resources/contenttype/test_resources/create.tf b/internal/resources/contenttype/test_resources/create.tf new file mode 100644 index 0000000..bb9778d --- /dev/null +++ b/internal/resources/contenttype/test_resources/create.tf @@ -0,0 +1,18 @@ +resource "contentful_contenttype" "{{ .identifier }}" { + space_id = "{{ .spaceId }}" +{{.id_definition}} + name = "tf_test1" + description = "{{.desc}}" + display_field = "field1" + fields = [{ + id = "field1" + name = "Field 1 name change" + required = true + type = "Text" + }, { + id = "field3" + name = "Field 3 new field" + required = true + type = "Integer" + }] +} \ No newline at end of file diff --git a/internal/resources/contenttype/test_resources/link_config.tf b/internal/resources/contenttype/test_resources/link_config.tf new file mode 100644 index 0000000..add70eb --- /dev/null +++ b/internal/resources/contenttype/test_resources/link_config.tf @@ -0,0 +1,51 @@ +resource "contentful_contenttype" "{{ .identifier }}" { + space_id = "{{ .spaceId }}" + name = "tf_test1" + description = "Terraform Acc Test Content Type description change" + display_field = "field1" + manage_field_controls = true + fields = [{ + id = "field1" + name = "Field 1 name change" + required = true + type = "Text" + }, { + id = "field3" + name = "Field 3 new field" + required = true + type = "Integer" + control = { + widget_id = "numberEditor" + widget_namespace = "builtin" + settings = { + help_text = "blabla" + bulk_editing = false + } + } + }] +} + +resource "contentful_contenttype" "{{ .linkIdentifier }}" { + space_id = "{{ .spaceId }}" + name = "tf_linked" + description = "Terraform Acc Test Content Type with links" + display_field = "asset_field" + fields =[{ + id = "asset_field" + name = "Asset Field" + type = "Array" + items = { + type = "Link" + link_type = "Asset" + } + required = true + },{ + id = "entry_link_field" + name = "Entry Link Field" + type = "Link" + link_type = "Entry" + validations = [{ + link_content_type = [contentful_contenttype.{{ .identifier }}.id ] + }] + }] +} \ No newline at end of file diff --git a/internal/resources/contenttype/test_resources/update.tf b/internal/resources/contenttype/test_resources/update.tf new file mode 100644 index 0000000..c6290df --- /dev/null +++ b/internal/resources/contenttype/test_resources/update.tf @@ -0,0 +1,26 @@ +resource "contentful_contenttype" "{{ .identifier }}" { + space_id = "{{ .spaceId }}" + name = "tf_test1" + description = "Terraform Acc Test Content Type description change" + display_field = "field1" + manage_field_controls = true + fields = [{ + id = "field1" + name = "Field 1 name change" + required = true + type = "Text" + }, { + id = "field3" + name = "Field 3 new field" + required = true + type = "Integer" + control = { + widget_id = "numberEditor" + widget_namespace = "builtin" + settings = { + help_text = "blabla" + bulk_editing = true + } + } + }] +} \ No newline at end of file diff --git a/internal/utils/hcl.go b/internal/utils/hcl.go index 5f8f9e1..c29bc72 100644 --- a/internal/utils/hcl.go +++ b/internal/utils/hcl.go @@ -2,6 +2,7 @@ package utils import ( "bytes" + "os" "text/template" ) @@ -14,3 +15,18 @@ func HCLTemplate(data string, params map[string]any) string { } return out.String() } + +func HCLTemplateFromPath(path string, params map[string]any) string { + data, err := os.ReadFile(path) + if err != nil { + panic(err) + } + + var out bytes.Buffer + tmpl := template.Must(template.New("hcl").Parse(string(data))) + err = tmpl.Execute(&out, params) + if err != nil { + panic(err) + } + return out.String() +} From 1c036042e3dc9e48893b3c5c0cd17c6f246743f0 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 15 Dec 2023 12:25:07 +0100 Subject: [PATCH 168/192] Release v1.4.0 (#24) Co-authored-by: Engerim --- .changes/unreleased/Added-20231215-115352.yaml | 3 --- .changes/v1.4.0.md | 3 +++ CHANGELOG.md | 4 ++++ 3 files changed, 7 insertions(+), 3 deletions(-) delete mode 100644 .changes/unreleased/Added-20231215-115352.yaml create mode 100644 .changes/v1.4.0.md diff --git a/.changes/unreleased/Added-20231215-115352.yaml b/.changes/unreleased/Added-20231215-115352.yaml deleted file mode 100644 index 882d1c7..0000000 --- a/.changes/unreleased/Added-20231215-115352.yaml +++ /dev/null @@ -1,3 +0,0 @@ -kind: Added -body: Add support for app_installations -time: 2023-12-15T11:53:52.030953+01:00 diff --git a/.changes/v1.4.0.md b/.changes/v1.4.0.md new file mode 100644 index 0000000..ee5d398 --- /dev/null +++ b/.changes/v1.4.0.md @@ -0,0 +1,3 @@ +## v1.4.0 - 2023-12-15 +### Added +* Add support for app_installations diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b5f3cb..373d6fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), and is generated by [Changie](https://github.com/miniscruff/changie). +## v1.4.0 - 2023-12-15 +### Added +* Add support for app_installations + ## v1.3.0 - 2023-12-08 ### Added * Add support app configuration in the organization From bd155c0bddd39757261376714024cc0b77f50c1f Mon Sep 17 00:00:00 2001 From: Alexander Miehe Date: Tue, 19 Dec 2023 12:53:32 +0100 Subject: [PATCH 169/192] PLT-0 - Use flaconi (#25) * use flaconi contentful fork * use flaconi all over the place * adjust code owners --- .../unreleased/Changed-20231215-173353.yaml | 3 +++ .../unreleased/Changed-20231215-174057.yaml | 3 +++ .github/CODEOWNERS | 2 +- .github/FUNDING.yml | 2 -- .github/pull-request-template.md | 27 ------------------- Makefile | 2 +- README.md | 7 +++-- contentful/provider.go | 2 +- contentful/resource_contentful_apikey.go | 2 +- contentful/resource_contentful_apikey_test.go | 2 +- contentful/resource_contentful_asset.go | 2 +- contentful/resource_contentful_asset_test.go | 2 +- contentful/resource_contentful_entry.go | 2 +- contentful/resource_contentful_entry_test.go | 2 +- contentful/resource_contentful_environment.go | 2 +- .../resource_contentful_environment_test.go | 2 +- contentful/resource_contentful_locale.go | 2 +- contentful/resource_contentful_locale_test.go | 2 +- contentful/resource_contentful_space.go | 2 +- contentful/resource_contentful_space_test.go | 2 +- contentful/resource_contentful_webhook.go | 2 +- .../resource_contentful_webhook_test.go | 2 +- go.mod | 6 ++--- internal/acctest/client.go | 2 +- internal/provider/provider.go | 10 +++---- internal/resources/app_definition/model.go | 4 +-- internal/resources/app_definition/resource.go | 8 +++--- .../resources/app_definition/resource_test.go | 8 +++--- internal/resources/app_installation/model.go | 2 +- .../resources/app_installation/resource.go | 4 +-- .../app_installation/resource_test.go | 8 +++--- internal/resources/contenttype/model.go | 4 +-- internal/resources/contenttype/resource.go | 8 +++--- .../resources/contenttype/resource_test.go | 8 +++--- internal/utils/container.go | 2 +- main.go | 4 +-- 36 files changed, 64 insertions(+), 90 deletions(-) create mode 100644 .changes/unreleased/Changed-20231215-173353.yaml create mode 100644 .changes/unreleased/Changed-20231215-174057.yaml delete mode 100644 .github/FUNDING.yml delete mode 100644 .github/pull-request-template.md diff --git a/.changes/unreleased/Changed-20231215-173353.yaml b/.changes/unreleased/Changed-20231215-173353.yaml new file mode 100644 index 0000000..384209e --- /dev/null +++ b/.changes/unreleased/Changed-20231215-173353.yaml @@ -0,0 +1,3 @@ +kind: Changed +body: Use flaconi fork of contentful lib +time: 2023-12-15T17:33:53.327812+01:00 diff --git a/.changes/unreleased/Changed-20231215-174057.yaml b/.changes/unreleased/Changed-20231215-174057.yaml new file mode 100644 index 0000000..ba22f2a --- /dev/null +++ b/.changes/unreleased/Changed-20231215-174057.yaml @@ -0,0 +1,3 @@ +kind: Changed +body: Replace labd with flaconi in the whole code base +time: 2023-12-15T17:40:57.932612+01:00 diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 00c946f..0fdec6f 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1 +1 @@ -* @labd/go +* @Flaconi/ci @Flaconi/platform diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml deleted file mode 100644 index 66c7a63..0000000 --- a/.github/FUNDING.yml +++ /dev/null @@ -1,2 +0,0 @@ -# These are supported funding model platform -github: [labd] diff --git a/.github/pull-request-template.md b/.github/pull-request-template.md deleted file mode 100644 index 4b4165c..0000000 --- a/.github/pull-request-template.md +++ /dev/null @@ -1,27 +0,0 @@ - - - - -Fixes # - -### NEW FEATURES | UPGRADE NOTES | ENHANCEMENTS | BUG FIXES | EXPERIMENTS - - - -- diff --git a/Makefile b/Makefile index 46a67b4..a486abd 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ test-unit: build interactive: sudo -S docker run -it \ - -v $(shell pwd):/go/src/github.com/labd/terraform-provider-contentful \ + -v $(shell pwd):/go/src/github.com/flaconi/terraform-provider-contentful \ -e CONTENTFUL_MANAGEMENT_TOKEN=${CONTENTFUL_MANAGEMENT_TOKEN} \ -e CONTENTFUL_ORGANIZATION_ID=${CONTENTFUL_ORGANIZATION_ID} \ -e SPACE_ID=${SPACE_ID} \ diff --git a/README.md b/README.md index cbeb1ed..940a4c9 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ -![Go](https://github.com/labd/terraform-provider-contentful/workflows/Go/badge.svg?branch=master) -[![codecov](https://codecov.io/gh/labd/terraform-provider-contentful/branch/master/graph/badge.svg)](https://codecov.io/gh/labd/terraform-provider-contentful) -[![license](https://img.shields.io/github/license/labd/terraform-provider-contentful.svg)](https://github.com/labd/terraform-provider-contentful/blob/master/LICENSE) +![Go](https://github.com/flaconi/terraform-provider-contentful/workflows/Go/badge.svg?branch=master) +[![license](https://img.shields.io/github/license/flaconi/terraform-provider-contentful.svg)](https://github.com/flaconi/terraform-provider-contentful/blob/master/LICENSE) Terraform Provider for [Contentful's](https://www.contentful.com) Content Management API @@ -150,7 +149,7 @@ Julien Fabre: [Writing a Terraform provider](http://blog.jfabre.net/2017/01/22/w ## Support -If you have a problem with this provider, please file an [issue](https://github.com/labd/terraform-provider-contentful/issues/new) here on Github. +If you have a problem with this provider, please file an [issue](https://github.com/flaconi/terraform-provider-contentful/issues/new) here on Github. ## License diff --git a/contentful/provider.go b/contentful/provider.go index d293937..f816b24 100644 --- a/contentful/provider.go +++ b/contentful/provider.go @@ -2,9 +2,9 @@ package contentful import ( "context" + "github.com/flaconi/contentful-go" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/labd/contentful-go" ) // Provider returns the Terraform Provider as a scheme and makes resources reachable diff --git a/contentful/resource_contentful_apikey.go b/contentful/resource_contentful_apikey.go index dbf758d..495e847 100644 --- a/contentful/resource_contentful_apikey.go +++ b/contentful/resource_contentful_apikey.go @@ -1,8 +1,8 @@ package contentful import ( + contentful "github.com/flaconi/contentful-go" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - contentful "github.com/labd/contentful-go" ) func resourceContentfulAPIKey() *schema.Resource { diff --git a/contentful/resource_contentful_apikey_test.go b/contentful/resource_contentful_apikey_test.go index 8102039..64e9584 100644 --- a/contentful/resource_contentful_apikey_test.go +++ b/contentful/resource_contentful_apikey_test.go @@ -4,10 +4,10 @@ import ( "fmt" "testing" + contentful "github.com/flaconi/contentful-go" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" - contentful "github.com/labd/contentful-go" ) func TestAccContentfulAPIKey_Basic(t *testing.T) { diff --git a/contentful/resource_contentful_asset.go b/contentful/resource_contentful_asset.go index b7b6a22..3150fd3 100644 --- a/contentful/resource_contentful_asset.go +++ b/contentful/resource_contentful_asset.go @@ -4,8 +4,8 @@ import ( "fmt" "time" + contentful "github.com/flaconi/contentful-go" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - contentful "github.com/labd/contentful-go" ) func resourceContentfulAsset() *schema.Resource { diff --git a/contentful/resource_contentful_asset_test.go b/contentful/resource_contentful_asset_test.go index 3f0eede..7c81313 100644 --- a/contentful/resource_contentful_asset_test.go +++ b/contentful/resource_contentful_asset_test.go @@ -4,9 +4,9 @@ import ( "fmt" "testing" + contentful "github.com/flaconi/contentful-go" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" - contentful "github.com/labd/contentful-go" ) func TestAccContentfulAsset_Basic(t *testing.T) { diff --git a/contentful/resource_contentful_entry.go b/contentful/resource_contentful_entry.go index f8d3431..1911017 100644 --- a/contentful/resource_contentful_entry.go +++ b/contentful/resource_contentful_entry.go @@ -1,8 +1,8 @@ package contentful import ( + contentful "github.com/flaconi/contentful-go" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - contentful "github.com/labd/contentful-go" ) func resourceContentfulEntry() *schema.Resource { diff --git a/contentful/resource_contentful_entry_test.go b/contentful/resource_contentful_entry_test.go index 30c7cb7..def2c2a 100644 --- a/contentful/resource_contentful_entry_test.go +++ b/contentful/resource_contentful_entry_test.go @@ -4,9 +4,9 @@ import ( "fmt" "testing" + contentful "github.com/flaconi/contentful-go" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" - contentful "github.com/labd/contentful-go" ) func TestAccContentfulEntry_Basic(t *testing.T) { diff --git a/contentful/resource_contentful_environment.go b/contentful/resource_contentful_environment.go index 4f4b254..ae4060f 100644 --- a/contentful/resource_contentful_environment.go +++ b/contentful/resource_contentful_environment.go @@ -1,8 +1,8 @@ package contentful import ( + contentful "github.com/flaconi/contentful-go" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - contentful "github.com/labd/contentful-go" ) func resourceContentfulEnvironment() *schema.Resource { diff --git a/contentful/resource_contentful_environment_test.go b/contentful/resource_contentful_environment_test.go index 2270bfc..0624afe 100644 --- a/contentful/resource_contentful_environment_test.go +++ b/contentful/resource_contentful_environment_test.go @@ -4,9 +4,9 @@ import ( "fmt" "testing" + contentful "github.com/flaconi/contentful-go" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" - contentful "github.com/labd/contentful-go" ) func TestAccContentfulEnvironment_Basic(t *testing.T) { diff --git a/contentful/resource_contentful_locale.go b/contentful/resource_contentful_locale.go index d257908..2609730 100644 --- a/contentful/resource_contentful_locale.go +++ b/contentful/resource_contentful_locale.go @@ -4,9 +4,9 @@ import ( "context" "errors" "fmt" + "github.com/flaconi/contentful-go" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/labd/contentful-go" "strings" ) diff --git a/contentful/resource_contentful_locale_test.go b/contentful/resource_contentful_locale_test.go index 596153c..910c2ba 100644 --- a/contentful/resource_contentful_locale_test.go +++ b/contentful/resource_contentful_locale_test.go @@ -5,9 +5,9 @@ import ( "fmt" "testing" + "github.com/flaconi/contentful-go" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" - "github.com/labd/contentful-go" ) func TestAccContentfulLocales_Basic(t *testing.T) { diff --git a/contentful/resource_contentful_space.go b/contentful/resource_contentful_space.go index adfae00..03acc3d 100644 --- a/contentful/resource_contentful_space.go +++ b/contentful/resource_contentful_space.go @@ -1,8 +1,8 @@ package contentful import ( + contentful "github.com/flaconi/contentful-go" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - contentful "github.com/labd/contentful-go" ) func resourceContentfulSpace() *schema.Resource { diff --git a/contentful/resource_contentful_space_test.go b/contentful/resource_contentful_space_test.go index 0f51d30..9dfd83f 100644 --- a/contentful/resource_contentful_space_test.go +++ b/contentful/resource_contentful_space_test.go @@ -4,9 +4,9 @@ import ( "fmt" "testing" + contentful "github.com/flaconi/contentful-go" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" - contentful "github.com/labd/contentful-go" ) func TestAccContentfulSpace_Basic(t *testing.T) { diff --git a/contentful/resource_contentful_webhook.go b/contentful/resource_contentful_webhook.go index 6119e9d..2573d9a 100644 --- a/contentful/resource_contentful_webhook.go +++ b/contentful/resource_contentful_webhook.go @@ -1,8 +1,8 @@ package contentful import ( + contentful "github.com/flaconi/contentful-go" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - contentful "github.com/labd/contentful-go" ) func resourceContentfulWebhook() *schema.Resource { diff --git a/contentful/resource_contentful_webhook_test.go b/contentful/resource_contentful_webhook_test.go index 5b0e1e4..719caf7 100644 --- a/contentful/resource_contentful_webhook_test.go +++ b/contentful/resource_contentful_webhook_test.go @@ -4,9 +4,9 @@ import ( "fmt" "testing" + contentful "github.com/flaconi/contentful-go" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" - contentful "github.com/labd/contentful-go" ) func TestAccContentfulWebhook_Basic(t *testing.T) { diff --git a/go.mod b/go.mod index e02f1a0..43319e0 100644 --- a/go.mod +++ b/go.mod @@ -1,16 +1,16 @@ -module github.com/labd/terraform-provider-contentful +module github.com/flaconi/terraform-provider-contentful go 1.21 require ( github.com/elliotchance/pie/v2 v2.8.0 + github.com/flaconi/contentful-go v0.5.3-0.20231215085749-a6bd885d770b github.com/hashicorp/terraform-plugin-docs v0.16.0 github.com/hashicorp/terraform-plugin-framework v1.4.2 github.com/hashicorp/terraform-plugin-framework-jsontypes v0.1.0 github.com/hashicorp/terraform-plugin-framework-validators v0.12.0 github.com/hashicorp/terraform-plugin-mux v0.12.0 github.com/hashicorp/terraform-plugin-testing v1.6.0 - github.com/labd/contentful-go v0.5.3 github.com/stretchr/testify v1.8.4 ) @@ -85,5 +85,3 @@ require ( google.golang.org/protobuf v1.31.0 // indirect moul.io/http2curl v1.0.1-0.20190925090545-5cd742060b0e // indirect ) - -replace github.com/labd/contentful-go v0.5.3 => github.com/flaconi/contentful-go v0.5.3-0.20231215085749-a6bd885d770b diff --git a/internal/acctest/client.go b/internal/acctest/client.go index 4ad62c7..25abe56 100644 --- a/internal/acctest/client.go +++ b/internal/acctest/client.go @@ -1,7 +1,7 @@ package acctest import ( - "github.com/labd/contentful-go" + "github.com/flaconi/contentful-go" "os" ) diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 5af834e..5f2ce15 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -2,16 +2,16 @@ package provider import ( "context" + "github.com/flaconi/contentful-go" + "github.com/flaconi/terraform-provider-contentful/internal/resources/app_definition" + "github.com/flaconi/terraform-provider-contentful/internal/resources/app_installation" + "github.com/flaconi/terraform-provider-contentful/internal/resources/contenttype" + "github.com/flaconi/terraform-provider-contentful/internal/utils" "github.com/hashicorp/terraform-plugin-framework/datasource" "github.com/hashicorp/terraform-plugin-framework/provider" "github.com/hashicorp/terraform-plugin-framework/provider/schema" "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/labd/contentful-go" - "github.com/labd/terraform-provider-contentful/internal/resources/app_definition" - "github.com/labd/terraform-provider-contentful/internal/resources/app_installation" - "github.com/labd/terraform-provider-contentful/internal/resources/contenttype" - "github.com/labd/terraform-provider-contentful/internal/utils" "os" ) diff --git a/internal/resources/app_definition/model.go b/internal/resources/app_definition/model.go index caf8829..7a0760a 100644 --- a/internal/resources/app_definition/model.go +++ b/internal/resources/app_definition/model.go @@ -2,9 +2,9 @@ package app_definition import ( "github.com/elliotchance/pie/v2" + "github.com/flaconi/contentful-go" + "github.com/flaconi/terraform-provider-contentful/internal/utils" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/labd/contentful-go" - "github.com/labd/terraform-provider-contentful/internal/utils" ) // AppDefinition is the main resource schema data diff --git a/internal/resources/app_definition/resource.go b/internal/resources/app_definition/resource.go index af519f7..daf8464 100644 --- a/internal/resources/app_definition/resource.go +++ b/internal/resources/app_definition/resource.go @@ -3,6 +3,10 @@ package app_definition import ( "context" _ "embed" + "github.com/flaconi/contentful-go" + "github.com/flaconi/terraform-provider-contentful/internal/custommodifier" + "github.com/flaconi/terraform-provider-contentful/internal/customvalidator" + "github.com/flaconi/terraform-provider-contentful/internal/utils" "github.com/hashicorp/terraform-plugin-framework-validators/listvalidator" "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" "github.com/hashicorp/terraform-plugin-framework/diag" @@ -14,10 +18,6 @@ import ( "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/tfsdk" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/labd/contentful-go" - "github.com/labd/terraform-provider-contentful/internal/custommodifier" - "github.com/labd/terraform-provider-contentful/internal/customvalidator" - "github.com/labd/terraform-provider-contentful/internal/utils" ) //go:embed bundle.zip diff --git a/internal/resources/app_definition/resource_test.go b/internal/resources/app_definition/resource_test.go index 9e8b899..6842013 100644 --- a/internal/resources/app_definition/resource_test.go +++ b/internal/resources/app_definition/resource_test.go @@ -3,14 +3,14 @@ package app_definition_test import ( "errors" "fmt" + "github.com/flaconi/contentful-go" + "github.com/flaconi/terraform-provider-contentful/internal/acctest" + "github.com/flaconi/terraform-provider-contentful/internal/provider" + "github.com/flaconi/terraform-provider-contentful/internal/utils" "github.com/hashicorp/terraform-plugin-framework/providerserver" "github.com/hashicorp/terraform-plugin-go/tfprotov6" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" - "github.com/labd/contentful-go" - "github.com/labd/terraform-provider-contentful/internal/acctest" - "github.com/labd/terraform-provider-contentful/internal/provider" - "github.com/labd/terraform-provider-contentful/internal/utils" "github.com/stretchr/testify/assert" "os" "regexp" diff --git a/internal/resources/app_installation/model.go b/internal/resources/app_installation/model.go index 539b10b..7c5e895 100644 --- a/internal/resources/app_installation/model.go +++ b/internal/resources/app_installation/model.go @@ -2,9 +2,9 @@ package app_installation import ( "encoding/json" + "github.com/flaconi/contentful-go" "github.com/hashicorp/terraform-plugin-framework-jsontypes/jsontypes" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/labd/contentful-go" ) // AppInstallation is the main resource schema data diff --git a/internal/resources/app_installation/resource.go b/internal/resources/app_installation/resource.go index 182401f..94d8053 100644 --- a/internal/resources/app_installation/resource.go +++ b/internal/resources/app_installation/resource.go @@ -6,6 +6,8 @@ import ( "errors" "fmt" "github.com/elliotchance/pie/v2" + "github.com/flaconi/contentful-go" + "github.com/flaconi/terraform-provider-contentful/internal/utils" "github.com/hashicorp/terraform-plugin-framework-jsontypes/jsontypes" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/resource" @@ -14,8 +16,6 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/tfsdk" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/labd/contentful-go" - "github.com/labd/terraform-provider-contentful/internal/utils" "strings" ) diff --git a/internal/resources/app_installation/resource_test.go b/internal/resources/app_installation/resource_test.go index cb007ad..c8744a4 100644 --- a/internal/resources/app_installation/resource_test.go +++ b/internal/resources/app_installation/resource_test.go @@ -3,14 +3,14 @@ package app_installation_test import ( "errors" "fmt" + "github.com/flaconi/contentful-go" + "github.com/flaconi/terraform-provider-contentful/internal/acctest" + "github.com/flaconi/terraform-provider-contentful/internal/provider" + "github.com/flaconi/terraform-provider-contentful/internal/utils" "github.com/hashicorp/terraform-plugin-framework/providerserver" "github.com/hashicorp/terraform-plugin-go/tfprotov6" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" - "github.com/labd/contentful-go" - "github.com/labd/terraform-provider-contentful/internal/acctest" - "github.com/labd/terraform-provider-contentful/internal/provider" - "github.com/labd/terraform-provider-contentful/internal/utils" "github.com/stretchr/testify/assert" "os" "testing" diff --git a/internal/resources/contenttype/model.go b/internal/resources/contenttype/model.go index 3d2d869..b087c67 100644 --- a/internal/resources/contenttype/model.go +++ b/internal/resources/contenttype/model.go @@ -4,11 +4,11 @@ import ( "encoding/json" "fmt" "github.com/elliotchance/pie/v2" + "github.com/flaconi/contentful-go" + "github.com/flaconi/terraform-provider-contentful/internal/utils" "github.com/hashicorp/terraform-plugin-framework-jsontypes/jsontypes" "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/labd/contentful-go" - "github.com/labd/terraform-provider-contentful/internal/utils" "reflect" ) diff --git a/internal/resources/contenttype/resource.go b/internal/resources/contenttype/resource.go index ec82bec..e41eff3 100644 --- a/internal/resources/contenttype/resource.go +++ b/internal/resources/contenttype/resource.go @@ -4,6 +4,10 @@ import ( "context" "fmt" "github.com/elliotchance/pie/v2" + "github.com/flaconi/contentful-go" + "github.com/flaconi/terraform-provider-contentful/internal/custommodifier" + "github.com/flaconi/terraform-provider-contentful/internal/customvalidator" + "github.com/flaconi/terraform-provider-contentful/internal/utils" "github.com/hashicorp/terraform-plugin-framework-jsontypes/jsontypes" "github.com/hashicorp/terraform-plugin-framework-validators/listvalidator" "github.com/hashicorp/terraform-plugin-framework-validators/objectvalidator" @@ -18,10 +22,6 @@ import ( "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/tfsdk" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/labd/contentful-go" - "github.com/labd/terraform-provider-contentful/internal/custommodifier" - "github.com/labd/terraform-provider-contentful/internal/customvalidator" - "github.com/labd/terraform-provider-contentful/internal/utils" "reflect" "strings" ) diff --git a/internal/resources/contenttype/resource_test.go b/internal/resources/contenttype/resource_test.go index 5eee94e..cd8bdbc 100644 --- a/internal/resources/contenttype/resource_test.go +++ b/internal/resources/contenttype/resource_test.go @@ -3,14 +3,14 @@ package contenttype_test import ( "errors" "fmt" + "github.com/flaconi/contentful-go" + "github.com/flaconi/terraform-provider-contentful/internal/acctest" + "github.com/flaconi/terraform-provider-contentful/internal/provider" + "github.com/flaconi/terraform-provider-contentful/internal/utils" "github.com/hashicorp/terraform-plugin-framework/providerserver" "github.com/hashicorp/terraform-plugin-go/tfprotov6" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" - "github.com/labd/contentful-go" - "github.com/labd/terraform-provider-contentful/internal/acctest" - "github.com/labd/terraform-provider-contentful/internal/provider" - "github.com/labd/terraform-provider-contentful/internal/utils" "github.com/stretchr/testify/assert" "os" diff --git a/internal/utils/container.go b/internal/utils/container.go index 6325a4d..eae3a42 100644 --- a/internal/utils/container.go +++ b/internal/utils/container.go @@ -1,6 +1,6 @@ package utils -import "github.com/labd/contentful-go" +import "github.com/flaconi/contentful-go" type ProviderData struct { Client *contentful.Client diff --git a/main.go b/main.go index 5434f7f..996a80d 100644 --- a/main.go +++ b/main.go @@ -4,13 +4,13 @@ import ( "context" "flag" "fmt" + "github.com/flaconi/terraform-provider-contentful/contentful" + "github.com/flaconi/terraform-provider-contentful/internal/provider" "github.com/hashicorp/terraform-plugin-framework/providerserver" "github.com/hashicorp/terraform-plugin-go/tfprotov6" "github.com/hashicorp/terraform-plugin-go/tfprotov6/tf6server" "github.com/hashicorp/terraform-plugin-mux/tf5to6server" "github.com/hashicorp/terraform-plugin-mux/tf6muxserver" - "github.com/labd/terraform-provider-contentful/contentful" - "github.com/labd/terraform-provider-contentful/internal/provider" "log" ) From 96d5073d38604ab39f39c2835022b37118f0027c Mon Sep 17 00:00:00 2001 From: Alexander Miehe Date: Tue, 19 Dec 2023 16:23:44 +0100 Subject: [PATCH 170/192] PLT-0 - Update API Keys (#27) * move api keys to new plugin structure * add preview tokens to api_keys --- .../unreleased/Added-20231219-161646.yaml | 3 + .../unreleased/Changed-20231219-161717.yaml | 3 + contentful/provider.go | 1 - contentful/resource_contentful_apikey.go | 138 --------- contentful/resource_contentful_apikey_test.go | 146 ---------- docs/resources/apikey.md | 13 +- go.mod | 4 +- go.sum | 4 +- internal/acctest/client.go | 18 +- internal/provider/provider.go | 25 +- internal/resources/api_key/model.go | 65 +++++ internal/resources/api_key/resource.go | 263 ++++++++++++++++++ internal/resources/api_key/resource_test.go | 131 +++++++++ .../api_key/test_resources/create.tf | 6 + .../api_key/test_resources/update.tf | 6 + internal/resources/app_installation/model.go | 29 +- .../resources/app_installation/resource.go | 29 +- .../app_installation/resource_test.go | 22 +- internal/utils/container.go | 6 +- 19 files changed, 582 insertions(+), 330 deletions(-) create mode 100644 .changes/unreleased/Added-20231219-161646.yaml create mode 100644 .changes/unreleased/Changed-20231219-161717.yaml delete mode 100644 contentful/resource_contentful_apikey.go delete mode 100644 contentful/resource_contentful_apikey_test.go create mode 100644 internal/resources/api_key/model.go create mode 100644 internal/resources/api_key/resource.go create mode 100644 internal/resources/api_key/resource_test.go create mode 100644 internal/resources/api_key/test_resources/create.tf create mode 100644 internal/resources/api_key/test_resources/update.tf diff --git a/.changes/unreleased/Added-20231219-161646.yaml b/.changes/unreleased/Added-20231219-161646.yaml new file mode 100644 index 0000000..5d42414 --- /dev/null +++ b/.changes/unreleased/Added-20231219-161646.yaml @@ -0,0 +1,3 @@ +kind: Added +body: Add support for preview api keys +time: 2023-12-19T16:16:46.427077+01:00 diff --git a/.changes/unreleased/Changed-20231219-161717.yaml b/.changes/unreleased/Changed-20231219-161717.yaml new file mode 100644 index 0000000..c30b182 --- /dev/null +++ b/.changes/unreleased/Changed-20231219-161717.yaml @@ -0,0 +1,3 @@ +kind: Changed +body: Use for app installation new client version +time: 2023-12-19T16:17:17.965641+01:00 diff --git a/contentful/provider.go b/contentful/provider.go index f816b24..0b91e79 100644 --- a/contentful/provider.go +++ b/contentful/provider.go @@ -29,7 +29,6 @@ func Provider() func() *schema.Provider { }, ResourcesMap: map[string]*schema.Resource{ "contentful_space": resourceContentfulSpace(), - "contentful_apikey": resourceContentfulAPIKey(), "contentful_webhook": resourceContentfulWebhook(), "contentful_locale": resourceContentfulLocale(), "contentful_environment": resourceContentfulEnvironment(), diff --git a/contentful/resource_contentful_apikey.go b/contentful/resource_contentful_apikey.go deleted file mode 100644 index 495e847..0000000 --- a/contentful/resource_contentful_apikey.go +++ /dev/null @@ -1,138 +0,0 @@ -package contentful - -import ( - contentful "github.com/flaconi/contentful-go" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" -) - -func resourceContentfulAPIKey() *schema.Resource { - return &schema.Resource{ - Create: resourceCreateAPIKey, - Read: resourceReadAPIKey, - Update: resourceUpdateAPIKey, - Delete: resourceDeleteAPIKey, - - Schema: map[string]*schema.Schema{ - "version": { - Type: schema.TypeInt, - Computed: true, - }, - "access_token": { - Type: schema.TypeString, - Computed: true, - }, - "space_id": { - Type: schema.TypeString, - Required: true, - }, - "name": { - Type: schema.TypeString, - Required: true, - }, - "description": { - Type: schema.TypeString, - Optional: true, - }, - }, - } -} - -func resourceCreateAPIKey(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Client) - - apiKey := &contentful.APIKey{ - Name: d.Get("name").(string), - Description: d.Get("description").(string), - } - - err = client.APIKeys.Upsert(d.Get("space_id").(string), apiKey) - if err != nil { - return err - } - - if err := setAPIKeyProperties(d, apiKey); err != nil { - return err - } - - d.SetId(apiKey.Sys.ID) - - return nil -} - -func resourceUpdateAPIKey(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Client) - spaceID := d.Get("space_id").(string) - apiKeyID := d.Id() - - apiKey, err := client.APIKeys.Get(spaceID, apiKeyID) - if err != nil { - return err - } - - apiKey.Name = d.Get("name").(string) - apiKey.Description = d.Get("description").(string) - - err = client.APIKeys.Upsert(spaceID, apiKey) - if err != nil { - return err - } - - if err := setAPIKeyProperties(d, apiKey); err != nil { - return err - } - - d.SetId(apiKey.Sys.ID) - - return nil -} - -func resourceReadAPIKey(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Client) - spaceID := d.Get("space_id").(string) - apiKeyID := d.Id() - - apiKey, err := client.APIKeys.Get(spaceID, apiKeyID) - if _, ok := err.(contentful.NotFoundError); ok { - d.SetId("") - return nil - } - - return setAPIKeyProperties(d, apiKey) -} - -func resourceDeleteAPIKey(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Client) - spaceID := d.Get("space_id").(string) - apiKeyID := d.Id() - - apiKey, err := client.APIKeys.Get(spaceID, apiKeyID) - if err != nil { - return err - } - - return client.APIKeys.Delete(spaceID, apiKey) -} - -func setAPIKeyProperties(d *schema.ResourceData, apiKey *contentful.APIKey) error { - if err := d.Set("space_id", apiKey.Sys.Space.Sys.ID); err != nil { - return err - } - - if err := d.Set("version", apiKey.Sys.Version); err != nil { - return err - } - - if err := d.Set("name", apiKey.Name); err != nil { - return err - } - - if err := d.Set("description", apiKey.Description); err != nil { - return err - } - - if err := d.Set("access_token", apiKey.AccessToken); err != nil { - return err - } - - return nil -} diff --git a/contentful/resource_contentful_apikey_test.go b/contentful/resource_contentful_apikey_test.go deleted file mode 100644 index 64e9584..0000000 --- a/contentful/resource_contentful_apikey_test.go +++ /dev/null @@ -1,146 +0,0 @@ -package contentful - -import ( - "fmt" - "testing" - - contentful "github.com/flaconi/contentful-go" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" -) - -func TestAccContentfulAPIKey_Basic(t *testing.T) { - var apiKey contentful.APIKey - - name := fmt.Sprintf("apikey-name-%s", acctest.RandString(3)) - description := fmt.Sprintf("apikey-description-%s", acctest.RandString(3)) - - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccContentfulAPIKeyDestroy, - Steps: []resource.TestStep{ - { - Config: testAccContentfulAPIKeyConfig(name, description), - Check: resource.ComposeTestCheckFunc( - testAccCheckContentfulAPIKeyExists("contentful_apikey.myapikey", &apiKey), - testAccCheckContentfulAPIKeyAttributes(&apiKey, map[string]interface{}{ - "space_id": spaceID, - "name": name, - "description": description, - }), - ), - }, - { - Config: testAccContentfulAPIKeyUpdateConfig(name, description), - Check: resource.ComposeTestCheckFunc( - testAccCheckContentfulAPIKeyExists("contentful_apikey.myapikey", &apiKey), - testAccCheckContentfulAPIKeyAttributes(&apiKey, map[string]interface{}{ - "space_id": spaceID, - "name": fmt.Sprintf("%s-updated", name), - "description": fmt.Sprintf("%s-updated", description), - }), - ), - }, - }, - }) -} - -func testAccCheckContentfulAPIKeyExists(n string, apiKey *contentful.APIKey) resource.TestCheckFunc { - return func(s *terraform.State) error { - rs, ok := s.RootModule().Resources[n] - if !ok { - return fmt.Errorf("not Found: %s", n) - } - - spaceID := rs.Primary.Attributes["space_id"] - if spaceID == "" { - return fmt.Errorf("no space_id is set") - } - - apiKeyID := rs.Primary.ID - if apiKeyID == "" { - return fmt.Errorf("no api key ID is set") - } - - client := testAccProvider.Meta().(*contentful.Client) - - contentfulAPIKey, err := client.APIKeys.Get(spaceID, apiKeyID) - if err != nil { - return err - } - - *apiKey = *contentfulAPIKey - - return nil - } -} - -func testAccCheckContentfulAPIKeyAttributes(apiKey *contentful.APIKey, attrs map[string]interface{}) resource.TestCheckFunc { - return func(s *terraform.State) error { - name := attrs["name"].(string) - if apiKey.Name != name { - return fmt.Errorf("APIKey name does not match: %s, %s", apiKey.Name, name) - } - - description := attrs["description"].(string) - if apiKey.Description != description { - return fmt.Errorf("APIKey description does not match: %s, %s", apiKey.Description, description) - } - - return nil - } -} - -func testAccContentfulAPIKeyDestroy(s *terraform.State) error { - for _, rs := range s.RootModule().Resources { - if rs.Type != "contentful_apikey" { - continue - } - - // get space id from resource data - spaceID := rs.Primary.Attributes["space_id"] - if spaceID == "" { - return fmt.Errorf("no space_id is set") - } - - apiKeyID := rs.Primary.ID - if apiKeyID == "" { - return fmt.Errorf("no apikey ID is set") - } - - client := testAccProvider.Meta().(*contentful.Client) - - _, err := client.APIKeys.Get(spaceID, apiKeyID) - if _, ok := err.(contentful.NotFoundError); ok { - return nil - } - - return fmt.Errorf("api Key still exists with id: %s", rs.Primary.ID) - } - - return nil -} - -func testAccContentfulAPIKeyConfig(name, description string) string { - return fmt.Sprintf(` -resource "contentful_apikey" "myapikey" { - space_id = "%s" - - name = "%s" - description = "%s" -} -`, spaceID, name, description) -} - -func testAccContentfulAPIKeyUpdateConfig(name, description string) string { - return fmt.Sprintf(` -resource "contentful_apikey" "myapikey" { - space_id = "%s" - - name = "%s-updated" - description = "%s-updated" -} -`, spaceID, name, description) -} diff --git a/docs/resources/apikey.md b/docs/resources/apikey.md index f847af3..26cc8a3 100644 --- a/docs/resources/apikey.md +++ b/docs/resources/apikey.md @@ -3,12 +3,12 @@ page_title: "contentful_apikey Resource - terraform-provider-contentful" subcategory: "" description: |- - + Todo for explaining apikey --- # contentful_apikey (Resource) - +Todo for explaining apikey ## Example Usage @@ -27,14 +27,17 @@ resource "contentful_apikey" "myapikey" { ### Required - `name` (String) -- `space_id` (String) +- `space_id` (String) space id ### Optional - `description` (String) +- `environments` (List of String) List of needed environments if not added then master is used ### Read-Only -- `access_token` (String) -- `id` (String) The ID of this resource. +- `access_token` (String, Sensitive) +- `id` (String) api key id +- `preview_id` (String) preview api key id +- `preview_token` (String, Sensitive) - `version` (Number) diff --git a/go.mod b/go.mod index 43319e0..1e64821 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.21 require ( github.com/elliotchance/pie/v2 v2.8.0 - github.com/flaconi/contentful-go v0.5.3-0.20231215085749-a6bd885d770b + github.com/flaconi/contentful-go v0.5.3-0.20231219101222-e8e6531b72bb github.com/hashicorp/terraform-plugin-docs v0.16.0 github.com/hashicorp/terraform-plugin-framework v1.4.2 github.com/hashicorp/terraform-plugin-framework-jsontypes v0.1.0 @@ -85,3 +85,5 @@ require ( google.golang.org/protobuf v1.31.0 // indirect moul.io/http2curl v1.0.1-0.20190925090545-5cd742060b0e // indirect ) + +//replace github.com/flaconi/contentful-go => /Users/alexander.miehe/projects/flaconi/go/contentful-go diff --git a/go.sum b/go.sum index 43f7e21..1498e2d 100644 --- a/go.sum +++ b/go.sum @@ -43,8 +43,8 @@ github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5Kwzbycv github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= -github.com/flaconi/contentful-go v0.5.3-0.20231215085749-a6bd885d770b h1:J/OqzU6GRbmRIjgl2OjjvhbokKgmBCR189c1xGbgAdY= -github.com/flaconi/contentful-go v0.5.3-0.20231215085749-a6bd885d770b/go.mod h1:ciVUTFqeUtSSNjuEQnYLqbXvAlPu/aiPU4CsUc6Ug80= +github.com/flaconi/contentful-go v0.5.3-0.20231219101222-e8e6531b72bb h1:dvDYCZj8Yu0ShiwsBLaiG3SL2iwIjyWYS77L9I8//jc= +github.com/flaconi/contentful-go v0.5.3-0.20231219101222-e8e6531b72bb/go.mod h1:L5DNUF3KQXA5z9iQGqV0KcqN++U4bBDPjBSMG/94GHQ= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= diff --git a/internal/acctest/client.go b/internal/acctest/client.go index 25abe56..5cbc7ec 100644 --- a/internal/acctest/client.go +++ b/internal/acctest/client.go @@ -2,6 +2,8 @@ package acctest import ( "github.com/flaconi/contentful-go" + client2 "github.com/flaconi/contentful-go/pkgs/client" + "github.com/flaconi/contentful-go/service/common" "os" ) @@ -11,6 +13,20 @@ func GetClient() *contentful.Client { cma := contentful.NewCMA(cmaToken) cma.SetOrganization(organizationId) - //cma.Debug = true return cma } + +func GetCMA() common.SpaceIdClientBuilder { + client, err := contentful.NewCMAV2(client2.ClientConfig{ + URL: "https://api.contentful.com", + Debug: false, + UserAgent: "terraform-provider-contentful-test", + Token: os.Getenv("CONTENTFUL_MANAGEMENT_TOKEN"), + }) + + if err != nil { + panic(err) + } + + return client +} diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 5f2ce15..8823fa1 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -3,6 +3,8 @@ package provider import ( "context" "github.com/flaconi/contentful-go" + client2 "github.com/flaconi/contentful-go/pkgs/client" + "github.com/flaconi/terraform-provider-contentful/internal/resources/api_key" "github.com/flaconi/terraform-provider-contentful/internal/resources/app_definition" "github.com/flaconi/terraform-provider-contentful/internal/resources/app_installation" "github.com/flaconi/terraform-provider-contentful/internal/resources/contenttype" @@ -87,14 +89,32 @@ func (c contentfulProvider) Configure(ctx context.Context, request provider.Conf cma := contentful.NewCMA(cmaToken) cma.SetOrganization(organizationId) - cma.Debug = c.debug + debug := c.debug if os.Getenv("TF_LOG") != "" { - cma.Debug = true + debug = true + } + + cma.Debug = debug + + client, err := contentful.NewCMAV2(client2.ClientConfig{ + URL: "https://api.contentful.com", + Debug: debug, + UserAgent: "terraform-provider-contentful", + Token: cmaToken, + }) + + if err != nil { + response.Diagnostics.AddError( + "error during creation of cma client", + err.Error(), + ) + return } data := utils.ProviderData{ Client: cma, + CMAClient: client, OrganizationId: organizationId, } @@ -111,5 +131,6 @@ func (c contentfulProvider) Resources(_ context.Context) []func() resource.Resou contenttype.NewContentTypeResource, app_definition.NewAppDefinitionResource, app_installation.NewAppInstallationResource, + api_key.NewApiKeyResource, } } diff --git a/internal/resources/api_key/model.go b/internal/resources/api_key/model.go new file mode 100644 index 0000000..d3d35fa --- /dev/null +++ b/internal/resources/api_key/model.go @@ -0,0 +1,65 @@ +package api_key + +import ( + "github.com/elliotchance/pie/v2" + "github.com/flaconi/contentful-go/pkgs/model" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +// ApiKey is the main resource schema data +type ApiKey struct { + ID types.String `tfsdk:"id"` + PreviewID types.String `tfsdk:"preview_id"` + SpaceId types.String `tfsdk:"space_id"` + Name types.String `tfsdk:"name"` + Description types.String `tfsdk:"description"` + Version types.Int64 `tfsdk:"version"` + AccessToken types.String `tfsdk:"access_token"` + PreviewToken types.String `tfsdk:"preview_token"` + Environments []types.String `tfsdk:"environments"` +} + +func (a *ApiKey) Import(n *model.APIKey) { + a.ID = types.StringValue(n.Sys.ID) + a.PreviewID = types.StringValue(n.PreviewAPIKey.Sys.ID) + a.SpaceId = types.StringValue(n.Sys.Space.Sys.ID) + a.Version = types.Int64Value(int64(n.Sys.Version)) + a.Name = types.StringValue(n.Name) + a.Description = types.StringNull() + if n.Description != "" { + a.Description = types.StringValue(n.Description) + } + + a.Environments = pie.Map(n.Environments, func(t model.Environments) types.String { + return types.StringValue(t.Sys.ID) + }) + + a.AccessToken = types.StringValue(n.AccessToken) +} + +func (a *ApiKey) Draft() *model.APIKey { + draft := &model.APIKey{} + + if !a.ID.IsUnknown() || !a.ID.IsNull() { + draft.Sys = &model.SpaceSys{BaseSys: model.BaseSys{ID: a.ID.ValueString(), Version: int(a.Version.ValueInt64())}} + + } + + if !a.Description.IsNull() && !a.Description.IsUnknown() { + draft.Description = a.Description.ValueString() + } + + draft.Environments = pie.Map(a.Environments, func(t types.String) model.Environments { + return model.Environments{ + Sys: model.BaseSys{ + ID: t.ValueString(), + Type: "Link", + LinkType: "Environment", + }, + } + }) + + draft.Name = a.Name.ValueString() + + return draft +} diff --git a/internal/resources/api_key/resource.go b/internal/resources/api_key/resource.go new file mode 100644 index 0000000..e608fca --- /dev/null +++ b/internal/resources/api_key/resource.go @@ -0,0 +1,263 @@ +package api_key + +import ( + "context" + "fmt" + "github.com/flaconi/contentful-go/pkgs/model" + "github.com/flaconi/contentful-go/service/common" + "github.com/flaconi/terraform-provider-contentful/internal/utils" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-framework/types" + "strings" +) + +// Ensure the implementation satisfies the expected interfaces. +var ( + _ resource.Resource = &apiKeyResource{} + _ resource.ResourceWithConfigure = &apiKeyResource{} + _ resource.ResourceWithImportState = &apiKeyResource{} +) + +func NewApiKeyResource() resource.Resource { + return &apiKeyResource{} +} + +// apiKeyResource is the resource implementation. +type apiKeyResource struct { + client common.SpaceIdClientBuilder +} + +func (e *apiKeyResource) Metadata(_ context.Context, request resource.MetadataRequest, response *resource.MetadataResponse) { + response.TypeName = request.ProviderTypeName + "_apikey" +} + +func (e *apiKeyResource) Schema(_ context.Context, _ resource.SchemaRequest, response *resource.SchemaResponse) { + + response.Schema = schema.Schema{ + Description: "Todo for explaining apikey", + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + Computed: true, + Description: "api key id", + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + }, + "preview_id": schema.StringAttribute{ + Computed: true, + Description: "preview api key id", + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + }, + "version": schema.Int64Attribute{ + Computed: true, + }, + "space_id": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + Description: "space id", + }, + "access_token": schema.StringAttribute{ + Computed: true, + Sensitive: true, + }, + "name": schema.StringAttribute{ + Required: true, + }, + "description": schema.StringAttribute{ + Optional: true, + }, + "preview_token": schema.StringAttribute{ + Computed: true, + Sensitive: true, + }, + "environments": schema.ListAttribute{ + Optional: true, + Description: "List of needed environments if not added then master is used", + ElementType: types.StringType, + }, + }, + } +} + +func (e *apiKeyResource) Configure(_ context.Context, request resource.ConfigureRequest, _ *resource.ConfigureResponse) { + if request.ProviderData == nil { + return + } + + data := request.ProviderData.(utils.ProviderData) + e.client = data.CMAClient +} + +func (e *apiKeyResource) Create(ctx context.Context, request resource.CreateRequest, response *resource.CreateResponse) { + var plan *ApiKey + response.Diagnostics.Append(request.Plan.Get(ctx, &plan)...) + if response.Diagnostics.HasError() { + return + } + + draft := plan.Draft() + + if err := e.client.WithSpaceId(plan.SpaceId.ValueString()).ApiKeys().Upsert(ctx, draft); err != nil { + response.Diagnostics.AddError("Error creating api_key", err.Error()) + return + } + + plan.Import(draft) + + previewApiKeyContentful, err := e.getPreviewApiKey(ctx, plan) + if err != nil { + response.Diagnostics.AddError( + "Error reading preview api key", + "Could not retrieve preview api key, unexpected error: "+err.Error(), + ) + return + } + + plan.PreviewToken = types.StringValue(previewApiKeyContentful.AccessToken) + + // Set state to fully populated data + response.Diagnostics.Append(response.State.Set(ctx, plan)...) + if response.Diagnostics.HasError() { + return + } +} + +func (e *apiKeyResource) Read(ctx context.Context, request resource.ReadRequest, response *resource.ReadResponse) { + // Get current state + var state *ApiKey + diags := request.State.Get(ctx, &state) + response.Diagnostics.Append(diags...) + if response.Diagnostics.HasError() { + return + } + + e.doRead(ctx, state, &response.State, &response.Diagnostics) +} + +func (e *apiKeyResource) Update(ctx context.Context, request resource.UpdateRequest, response *resource.UpdateResponse) { + // Retrieve values from plan + var plan *ApiKey + diags := request.Plan.Get(ctx, &plan) + response.Diagnostics.Append(diags...) + if response.Diagnostics.HasError() { + return + } + + // Get current state + var state *ApiKey + diags = request.State.Get(ctx, &state) + response.Diagnostics.Append(diags...) + if response.Diagnostics.HasError() { + return + } + + draft := plan.Draft() + + if err := e.client.WithSpaceId(state.SpaceId.ValueString()).ApiKeys().Upsert(ctx, draft); err != nil { + response.Diagnostics.AddError( + "Error updating api key", + "Could not update api key, unexpected error: "+err.Error(), + ) + return + } + + plan.Import(draft) + + previewApiKeyContentful, err := e.getPreviewApiKey(ctx, plan) + if err != nil { + response.Diagnostics.AddError( + "Error reading preview api key", + "Could not retrieve preview api key, unexpected error: "+err.Error(), + ) + return + } + + plan.PreviewToken = types.StringValue(previewApiKeyContentful.AccessToken) + + // Set state to fully populated data + response.Diagnostics.Append(response.State.Set(ctx, plan)...) + if response.Diagnostics.HasError() { + return + } +} + +func (e *apiKeyResource) Delete(ctx context.Context, request resource.DeleteRequest, response *resource.DeleteResponse) { + // Get current state + var state *ApiKey + response.Diagnostics.Append(request.State.Get(ctx, &state)...) + + if err := e.client.WithSpaceId(state.SpaceId.ValueString()).ApiKeys().Delete(ctx, state.Draft()); err != nil { + response.Diagnostics.AddError( + "Error deleting api_key", + "Could not delete api_key, unexpected error: "+err.Error(), + ) + return + } +} + +func (e *apiKeyResource) ImportState(ctx context.Context, request resource.ImportStateRequest, response *resource.ImportStateResponse) { + idParts := strings.SplitN(request.ID, ":", 2) + + if len(idParts) != 2 || idParts[0] == "" || idParts[1] == "" { + response.Diagnostics.AddError( + "Unexpected Import Identifier", + fmt.Sprintf("Expected import identifier with format: apiKeyId:spaceId. Got: %q", request.ID), + ) + return + } + + futureState := &ApiKey{ + ID: types.StringValue(idParts[0]), + SpaceId: types.StringValue(idParts[1]), + } + + e.doRead(ctx, futureState, &response.State, &response.Diagnostics) +} + +func (e *apiKeyResource) doRead(ctx context.Context, apiKey *ApiKey, state *tfsdk.State, d *diag.Diagnostics) { + + apiKeyContentful, err := e.getApiKey(ctx, apiKey) + if err != nil { + d.AddError( + "Error reading api key", + "Could not retrieve api key, unexpected error: "+err.Error(), + ) + return + } + + apiKey.Import(apiKeyContentful) + + previewApiKeyContentful, err := e.getPreviewApiKey(ctx, apiKey) + if err != nil { + d.AddError( + "Error reading preview api key", + "Could not retrieve preview api key, unexpected error: "+err.Error(), + ) + return + } + + apiKey.PreviewToken = types.StringValue(previewApiKeyContentful.AccessToken) + + // Set refreshed state + d.Append(state.Set(ctx, &apiKey)...) + if d.HasError() { + return + } +} + +func (e *apiKeyResource) getApiKey(ctx context.Context, apiKey *ApiKey) (*model.APIKey, error) { + return e.client.WithSpaceId(apiKey.SpaceId.ValueString()).ApiKeys().Get(ctx, apiKey.ID.ValueString()) +} + +func (e *apiKeyResource) getPreviewApiKey(ctx context.Context, apiKey *ApiKey) (*model.PreviewAPIKey, error) { + return e.client.WithSpaceId(apiKey.SpaceId.ValueString()).PreviewApiKeys().Get(ctx, apiKey.PreviewID.ValueString()) +} diff --git a/internal/resources/api_key/resource_test.go b/internal/resources/api_key/resource_test.go new file mode 100644 index 0000000..e389939 --- /dev/null +++ b/internal/resources/api_key/resource_test.go @@ -0,0 +1,131 @@ +package api_key_test + +import ( + "context" + "errors" + "fmt" + "github.com/flaconi/contentful-go/pkgs/common" + "github.com/flaconi/contentful-go/pkgs/model" + "github.com/flaconi/terraform-provider-contentful/internal/acctest" + "github.com/flaconi/terraform-provider-contentful/internal/provider" + "github.com/flaconi/terraform-provider-contentful/internal/utils" + "github.com/hashicorp/terraform-plugin-framework/providerserver" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" + hashicor_acctest "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" + "github.com/stretchr/testify/assert" + "os" + "regexp" + "testing" +) + +type assertFunc func(*testing.T, *model.APIKey) + +func TestApiKeyResource_Create(t *testing.T) { + name := fmt.Sprintf("apikey-name-%s", hashicor_acctest.RandString(3)) + description := fmt.Sprintf("apikey-description-%s", hashicor_acctest.RandString(3)) + resourceName := "contentful_apikey.myapikey" + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.TestAccPreCheck(t) }, + CheckDestroy: testAccCheckContentfulApiKeyDestroy, + ProtoV6ProviderFactories: map[string]func() (tfprotov6.ProviderServer, error){ + "contentful": providerserver.NewProtocol6WithError(provider.New("test", true)), + }, + Steps: []resource.TestStep{ + { + Config: testApiKey(os.Getenv("CONTENTFUL_SPACE_ID"), name, description), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "name", name), + resource.TestCheckResourceAttr(resourceName, "description", description), + resource.TestMatchResourceAttr(resourceName, "id", regexp.MustCompile(`^[a-zA-Z0-9-_.]{1,64}$`)), + resource.TestMatchResourceAttr(resourceName, "preview_id", regexp.MustCompile(`^[a-zA-Z0-9-_.]{1,64}$`)), + testAccCheckContentfulApiKeyExists(t, resourceName, func(t *testing.T, apiKey *model.APIKey) { + assert.NotEmpty(t, apiKey.AccessToken) + assert.EqualValues(t, name, apiKey.Name) + assert.EqualValues(t, description, apiKey.Description) + assert.Regexp(t, regexp.MustCompile(`^[a-zA-Z0-9-_.]{1,64}$`), apiKey.Sys.ID) + }), + ), + }, + { + Config: testApiKeyUpdate(os.Getenv("CONTENTFUL_SPACE_ID"), name, description), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "name", fmt.Sprintf("%s-updated", name)), + resource.TestCheckResourceAttr(resourceName, "description", fmt.Sprintf("%s-updated", description)), + resource.TestMatchResourceAttr(resourceName, "id", regexp.MustCompile(`^[a-zA-Z0-9-_.]{1,64}$`)), + resource.TestMatchResourceAttr(resourceName, "preview_id", regexp.MustCompile(`^[a-zA-Z0-9-_.]{1,64}$`)), + testAccCheckContentfulApiKeyExists(t, resourceName, func(t *testing.T, apiKey *model.APIKey) { + assert.NotEmpty(t, apiKey.AccessToken) + assert.EqualValues(t, fmt.Sprintf("%s-updated", name), apiKey.Name) + assert.EqualValues(t, fmt.Sprintf("%s-updated", description), apiKey.Description) + assert.Regexp(t, regexp.MustCompile(`^[a-zA-Z0-9-_.]{1,64}$`), apiKey.Sys.ID) + }), + ), + }, + }, + }) +} + +func testAccCheckContentfulApiKeyExists(t *testing.T, resourceName string, assertFunc assertFunc) resource.TestCheckFunc { + return func(s *terraform.State) error { + definition, err := getApiKeyFromState(s, resourceName) + if err != nil { + return err + } + + assertFunc(t, definition) + return nil + } +} + +func getApiKeyFromState(s *terraform.State, resourceName string) (*model.APIKey, error) { + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return nil, fmt.Errorf("api key not found") + } + + if rs.Primary.ID == "" { + return nil, fmt.Errorf("no api key ID found") + } + + client := acctest.GetCMA() + + return client.WithSpaceId(os.Getenv("CONTENTFUL_SPACE_ID")).ApiKeys().Get(context.Background(), rs.Primary.ID) +} + +func testAccCheckContentfulApiKeyDestroy(s *terraform.State) error { + client := acctest.GetCMA() + + for _, rs := range s.RootModule().Resources { + if rs.Type != "contentful_apikey" { + continue + } + + _, err := client.WithSpaceId(os.Getenv("CONTENTFUL_SPACE_ID")).ApiKeys().Get(context.Background(), rs.Primary.ID) + var notFoundError common.NotFoundError + if errors.As(err, ¬FoundError) { + return nil + } + + return fmt.Errorf("api key still exists with id: %s", rs.Primary.ID) + } + + return nil +} + +func testApiKey(spaceId string, name string, description string) string { + return utils.HCLTemplateFromPath("test_resources/create.tf", map[string]any{ + "spaceId": spaceId, + "name": name, + "description": description, + }) +} + +func testApiKeyUpdate(spaceId string, name string, description string) string { + return utils.HCLTemplateFromPath("test_resources/update.tf", map[string]any{ + "spaceId": spaceId, + "name": name, + "description": description, + }) +} diff --git a/internal/resources/api_key/test_resources/create.tf b/internal/resources/api_key/test_resources/create.tf new file mode 100644 index 0000000..9cd4761 --- /dev/null +++ b/internal/resources/api_key/test_resources/create.tf @@ -0,0 +1,6 @@ +resource "contentful_apikey" "myapikey" { + space_id = "{{ .spaceId }}" + + name = "{{ .name }}" + description = "{{ .description }}" +} \ No newline at end of file diff --git a/internal/resources/api_key/test_resources/update.tf b/internal/resources/api_key/test_resources/update.tf new file mode 100644 index 0000000..1cb8387 --- /dev/null +++ b/internal/resources/api_key/test_resources/update.tf @@ -0,0 +1,6 @@ +resource "contentful_apikey" "myapikey" { + space_id = "{{ .spaceId }}" + + name = "{{ .name }}-updated" + description = "{{ .description }}-updated" +} \ No newline at end of file diff --git a/internal/resources/app_installation/model.go b/internal/resources/app_installation/model.go index 7c5e895..0026bd2 100644 --- a/internal/resources/app_installation/model.go +++ b/internal/resources/app_installation/model.go @@ -2,7 +2,8 @@ package app_installation import ( "encoding/json" - "github.com/flaconi/contentful-go" + "github.com/elliotchance/pie/v2" + "github.com/flaconi/contentful-go/pkgs/model" "github.com/hashicorp/terraform-plugin-framework-jsontypes/jsontypes" "github.com/hashicorp/terraform-plugin-framework/types" ) @@ -17,20 +18,38 @@ type AppInstallation struct { AcceptedTerms []types.String `tfsdk:"accepted_terms"` } -func (a *AppInstallation) Draft() *contentful.AppInstallation { +func (a *AppInstallation) Draft() *model.AppInstallation { - app := &contentful.AppInstallation{} + app := &model.AppInstallation{} parameters := make(map[string]any) a.Parameters.Unmarshal(¶meters) + if !a.AppDefinitionID.IsUnknown() || !a.AppDefinitionID.IsNull() { + + appDefinitionSys := struct { + Sys model.BaseSys + }{ + Sys: model.BaseSys{ + ID: a.AppDefinitionID.ValueString(), + }, + } + + app.Sys = &model.AppInstallationSys{AppDefinition: (*struct { + Sys model.BaseSys `json:"sys,omitempty"` + })(&appDefinitionSys)} + } + + app.Terms = pie.Map(a.AcceptedTerms, func(t types.String) string { + return t.ValueString() + }) app.Parameters = parameters return app } -func (a *AppInstallation) Equal(n *contentful.AppInstallation) bool { +func (a *AppInstallation) Equal(n *model.AppInstallation) bool { data, _ := json.Marshal(n.Parameters) @@ -41,7 +60,7 @@ func (a *AppInstallation) Equal(n *contentful.AppInstallation) bool { return true } -func (a *AppInstallation) Import(n *contentful.AppInstallation) { +func (a *AppInstallation) Import(n *model.AppInstallation) { a.AppDefinitionID = types.StringValue(n.Sys.AppDefinition.Sys.ID) a.ID = types.StringValue(n.Sys.AppDefinition.Sys.ID) data, _ := json.Marshal(n.Parameters) diff --git a/internal/resources/app_installation/resource.go b/internal/resources/app_installation/resource.go index 94d8053..8b856b9 100644 --- a/internal/resources/app_installation/resource.go +++ b/internal/resources/app_installation/resource.go @@ -5,8 +5,9 @@ import ( _ "embed" "errors" "fmt" - "github.com/elliotchance/pie/v2" "github.com/flaconi/contentful-go" + "github.com/flaconi/contentful-go/pkgs/model" + "github.com/flaconi/contentful-go/service/common" "github.com/flaconi/terraform-provider-contentful/internal/utils" "github.com/hashicorp/terraform-plugin-framework-jsontypes/jsontypes" "github.com/hashicorp/terraform-plugin-framework/diag" @@ -32,7 +33,7 @@ func NewAppInstallationResource() resource.Resource { // appInstallationResource is the resource implementation. type appInstallationResource struct { - client *contentful.Client + client common.SpaceIdClientBuilder organizationId string } @@ -87,7 +88,7 @@ func (e *appInstallationResource) Configure(_ context.Context, request resource. } data := request.ProviderData.(utils.ProviderData) - e.client = data.Client + e.client = data.CMAClient e.organizationId = data.OrganizationId } @@ -101,11 +102,7 @@ func (e *appInstallationResource) Create(ctx context.Context, request resource.C draft := plan.Draft() - terms := pie.Map(plan.AcceptedTerms, func(t types.String) string { - return t.ValueString() - }) - - if err := e.client.AppInstallations.Upsert(plan.SpaceId.ValueString(), plan.AppDefinitionID.ValueString(), draft, plan.Environment.ValueString(), terms); err != nil { + if err := e.client.WithSpaceId(plan.SpaceId.ValueString()).WithEnvironment(plan.Environment.ValueString()).AppInstallations().Upsert(ctx, draft); err != nil { var errorResponse contentful.ErrorResponse if errors.As(err, &errorResponse) { if errorResponse.Error() == "Forbidden" { @@ -140,7 +137,7 @@ func (e *appInstallationResource) Read(ctx context.Context, request resource.Rea func (e *appInstallationResource) doRead(ctx context.Context, app *AppInstallation, state *tfsdk.State, d *diag.Diagnostics) { - appDefinition, err := e.getAppInstallation(app) + appDefinition, err := e.getAppInstallation(ctx, app) if err != nil { d.AddError( "Error reading app installation", @@ -175,7 +172,7 @@ func (e *appInstallationResource) Update(ctx context.Context, request resource.U return } - appDefinition, err := e.getAppInstallation(plan) + appDefinition, err := e.getAppInstallation(ctx, plan) if err != nil { response.Diagnostics.AddError( "Error reading app installation", @@ -188,11 +185,7 @@ func (e *appInstallationResource) Update(ctx context.Context, request resource.U draft := plan.Draft() - terms := pie.Map(plan.AcceptedTerms, func(t types.String) string { - return t.ValueString() - }) - - if err = e.client.AppInstallations.Upsert(plan.SpaceId.ValueString(), plan.AppDefinitionID.ValueString(), draft, plan.Environment.ValueString(), terms); err != nil { + if err = e.client.WithSpaceId(state.SpaceId.ValueString()).WithEnvironment(state.Environment.ValueString()).AppInstallations().Upsert(ctx, draft); err != nil { response.Diagnostics.AddError( "Error updating app installation", "Could not update app installation, unexpected error: "+err.Error(), @@ -209,7 +202,7 @@ func (e *appInstallationResource) Delete(ctx context.Context, request resource.D var state *AppInstallation response.Diagnostics.Append(request.State.Get(ctx, &state)...) - if err := e.client.AppInstallations.Delete(state.SpaceId.ValueString(), state.AppDefinitionID.ValueString(), state.Environment.ValueString()); err != nil { + if err := e.client.WithSpaceId(state.SpaceId.ValueString()).WithEnvironment(state.Environment.ValueString()).AppInstallations().Delete(ctx, state.Draft()); err != nil { response.Diagnostics.AddError( "Error deleting app_installation", "Could not delete app_installation, unexpected error: "+err.Error(), @@ -239,6 +232,6 @@ func (e *appInstallationResource) ImportState(ctx context.Context, request resou e.doRead(ctx, futureState, &response.State, &response.Diagnostics) } -func (e *appInstallationResource) getAppInstallation(app *AppInstallation) (*contentful.AppInstallation, error) { - return e.client.AppInstallations.Get(app.SpaceId.ValueString(), app.AppDefinitionID.ValueString(), app.Environment.ValueString()) +func (e *appInstallationResource) getAppInstallation(ctx context.Context, app *AppInstallation) (*model.AppInstallation, error) { + return e.client.WithSpaceId(app.SpaceId.ValueString()).WithEnvironment(app.Environment.ValueString()).AppInstallations().Get(ctx, app.AppDefinitionID.ValueString()) } diff --git a/internal/resources/app_installation/resource_test.go b/internal/resources/app_installation/resource_test.go index c8744a4..3c4db46 100644 --- a/internal/resources/app_installation/resource_test.go +++ b/internal/resources/app_installation/resource_test.go @@ -1,9 +1,11 @@ package app_installation_test import ( + "context" "errors" "fmt" - "github.com/flaconi/contentful-go" + "github.com/flaconi/contentful-go/pkgs/common" + "github.com/flaconi/contentful-go/pkgs/model" "github.com/flaconi/terraform-provider-contentful/internal/acctest" "github.com/flaconi/terraform-provider-contentful/internal/provider" "github.com/flaconi/terraform-provider-contentful/internal/utils" @@ -16,7 +18,7 @@ import ( "testing" ) -type assertFunc func(*testing.T, *contentful.AppInstallation) +type assertFunc func(*testing.T, *model.AppInstallation) func TestAppInstallation_Create(t *testing.T) { resourceName := "contentful_app_installation.acctest_app_installation" @@ -35,7 +37,7 @@ func TestAppInstallation_Create(t *testing.T) { Config: testAppInstallation("acctest_app_installation", os.Getenv("CONTENTFUL_SPACE_ID"), "master", appInstallationId), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(resourceName, "app_definition_id", appInstallationId), - testAccCheckContentfulAppInstallationExists(t, resourceName, func(t *testing.T, appInstallation *contentful.AppInstallation) { + testAccCheckContentfulAppInstallationExists(t, resourceName, func(t *testing.T, appInstallation *model.AppInstallation) { assert.IsType(t, map[string]any{}, appInstallation.Parameters) assert.Len(t, appInstallation.Parameters, 0) assert.EqualValues(t, appInstallationId, appInstallation.Sys.AppDefinition.Sys.ID) @@ -46,7 +48,7 @@ func TestAppInstallation_Create(t *testing.T) { Config: testAppInstallationWithParameter("acctest_app_installation_2", os.Getenv("CONTENTFUL_SPACE_ID"), "master", otherId), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("contentful_app_installation.acctest_app_installation_2", "app_definition_id", otherId), - testAccCheckContentfulAppInstallationExists(t, "contentful_app_installation.acctest_app_installation_2", func(t *testing.T, appInstallation *contentful.AppInstallation) { + testAccCheckContentfulAppInstallationExists(t, "contentful_app_installation.acctest_app_installation_2", func(t *testing.T, appInstallation *model.AppInstallation) { assert.IsType(t, map[string]any{}, appInstallation.Parameters) assert.Len(t, appInstallation.Parameters, 1) assert.EqualValues(t, "not-working-ever", appInstallation.Parameters["cpaToken"]) @@ -58,7 +60,7 @@ func TestAppInstallation_Create(t *testing.T) { }) } -func getAppInstallationFromState(s *terraform.State, resourceName string) (*contentful.AppInstallation, error) { +func getAppInstallationFromState(s *terraform.State, resourceName string) (*model.AppInstallation, error) { rs, ok := s.RootModule().Resources[resourceName] if !ok { return nil, fmt.Errorf("app installation not found") @@ -68,9 +70,9 @@ func getAppInstallationFromState(s *terraform.State, resourceName string) (*cont return nil, fmt.Errorf("no app installation ID found") } - client := acctest.GetClient() + client := acctest.GetCMA() - return client.AppInstallations.Get(os.Getenv("CONTENTFUL_SPACE_ID"), rs.Primary.ID, "master") + return client.WithSpaceId(os.Getenv("CONTENTFUL_SPACE_ID")).WithEnvironment("master").AppInstallations().Get(context.Background(), rs.Primary.ID) } func testAccCheckContentfulAppInstallationExists(t *testing.T, resourceName string, assertFunc assertFunc) resource.TestCheckFunc { @@ -86,15 +88,15 @@ func testAccCheckContentfulAppInstallationExists(t *testing.T, resourceName stri } func testAccCheckContentfulAppInstallationDestroy(s *terraform.State) error { - client := acctest.GetClient() + client := acctest.GetCMA() for _, rs := range s.RootModule().Resources { if rs.Type != "contentful_app_installation" { continue } - _, err := client.AppInstallations.Get(os.Getenv("CONTENTFUL_ORGANIZATION_ID"), rs.Primary.ID, "master") - var notFoundError contentful.NotFoundError + _, err := client.WithSpaceId(os.Getenv("CONTENTFUL_SPACE_ID")).WithEnvironment("master").AppInstallations().Get(context.Background(), rs.Primary.ID) + var notFoundError common.NotFoundError if errors.As(err, ¬FoundError) { return nil } diff --git a/internal/utils/container.go b/internal/utils/container.go index eae3a42..9525b3b 100644 --- a/internal/utils/container.go +++ b/internal/utils/container.go @@ -1,8 +1,12 @@ package utils -import "github.com/flaconi/contentful-go" +import ( + "github.com/flaconi/contentful-go" + "github.com/flaconi/contentful-go/service/common" +) type ProviderData struct { Client *contentful.Client + CMAClient common.SpaceIdClientBuilder OrganizationId string } From 3248219e2a245676e19a85762eac7b273cf39ae1 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 19 Dec 2023 16:31:18 +0100 Subject: [PATCH 171/192] Release v2.0.0 (#26) Co-authored-by: Engerim --- .changes/unreleased/Added-20231219-161646.yaml | 3 --- .changes/unreleased/Changed-20231215-173353.yaml | 3 --- .changes/unreleased/Changed-20231215-174057.yaml | 3 --- .changes/unreleased/Changed-20231219-161717.yaml | 3 --- .changes/v2.0.0.md | 7 +++++++ CHANGELOG.md | 8 ++++++++ 6 files changed, 15 insertions(+), 12 deletions(-) delete mode 100644 .changes/unreleased/Added-20231219-161646.yaml delete mode 100644 .changes/unreleased/Changed-20231215-173353.yaml delete mode 100644 .changes/unreleased/Changed-20231215-174057.yaml delete mode 100644 .changes/unreleased/Changed-20231219-161717.yaml create mode 100644 .changes/v2.0.0.md diff --git a/.changes/unreleased/Added-20231219-161646.yaml b/.changes/unreleased/Added-20231219-161646.yaml deleted file mode 100644 index 5d42414..0000000 --- a/.changes/unreleased/Added-20231219-161646.yaml +++ /dev/null @@ -1,3 +0,0 @@ -kind: Added -body: Add support for preview api keys -time: 2023-12-19T16:16:46.427077+01:00 diff --git a/.changes/unreleased/Changed-20231215-173353.yaml b/.changes/unreleased/Changed-20231215-173353.yaml deleted file mode 100644 index 384209e..0000000 --- a/.changes/unreleased/Changed-20231215-173353.yaml +++ /dev/null @@ -1,3 +0,0 @@ -kind: Changed -body: Use flaconi fork of contentful lib -time: 2023-12-15T17:33:53.327812+01:00 diff --git a/.changes/unreleased/Changed-20231215-174057.yaml b/.changes/unreleased/Changed-20231215-174057.yaml deleted file mode 100644 index ba22f2a..0000000 --- a/.changes/unreleased/Changed-20231215-174057.yaml +++ /dev/null @@ -1,3 +0,0 @@ -kind: Changed -body: Replace labd with flaconi in the whole code base -time: 2023-12-15T17:40:57.932612+01:00 diff --git a/.changes/unreleased/Changed-20231219-161717.yaml b/.changes/unreleased/Changed-20231219-161717.yaml deleted file mode 100644 index c30b182..0000000 --- a/.changes/unreleased/Changed-20231219-161717.yaml +++ /dev/null @@ -1,3 +0,0 @@ -kind: Changed -body: Use for app installation new client version -time: 2023-12-19T16:17:17.965641+01:00 diff --git a/.changes/v2.0.0.md b/.changes/v2.0.0.md new file mode 100644 index 0000000..dfbd8e4 --- /dev/null +++ b/.changes/v2.0.0.md @@ -0,0 +1,7 @@ +## v2.0.0 - 2023-12-19 +### Added +* Add support for preview api keys +### Changed +* Use flaconi fork of contentful lib +* Replace labd with flaconi in the whole code base +* Use for app installation new client version diff --git a/CHANGELOG.md b/CHANGELOG.md index 373d6fd..b88dfb6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,14 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), and is generated by [Changie](https://github.com/miniscruff/changie). +## v2.0.0 - 2023-12-19 +### Added +* Add support for preview api keys +### Changed +* Use flaconi fork of contentful lib +* Replace labd with flaconi in the whole code base +* Use for app installation new client version + ## v1.4.0 - 2023-12-15 ### Added * Add support for app_installations From c797003d04dcaf2bfb7a444f0c0a424506e8d3dd Mon Sep 17 00:00:00 2001 From: Alexander Miehe Date: Mon, 11 Mar 2024 10:32:24 +0100 Subject: [PATCH 172/192] PLT-824 - Fixing for duplicated fields in content type (#28) * PLT-824 - Fixing for duplicated fields in content type * update golang deps to the underlying sdk * add unique value check for content type fields * PLT-824 - Fixing for duplicated fields in content type * update golang deps to the underlying sdk * add unique value check for content type fields * PLT-824 - Fixing for duplicated fields in content type * improve tests --- .../unreleased/Added-20240306-110007.yaml | 3 + .../unreleased/Added-20240306-110048.yaml | 3 + .../unreleased/Changed-20240306-105943.yaml | 3 + contentful/provider.go | 24 +- contentful/resource_contentful_asset.go | 245 +++++++++--------- contentful/resource_contentful_asset_test.go | 25 +- contentful/resource_contentful_entry.go | 67 +++-- contentful/resource_contentful_entry_test.go | 25 +- contentful/resource_contentful_environment.go | 35 ++- .../resource_contentful_environment_test.go | 36 +-- contentful/resource_contentful_locale.go | 88 ++----- contentful/resource_contentful_locale_test.go | 27 +- contentful/resource_contentful_space.go | 14 +- contentful/resource_contentful_webhook.go | 14 +- .../resource_contentful_webhook_test.go | 8 +- .../resources/contentful_asset/resource.tf | 2 +- .../resources/contentful_entry/resource.tf | 2 +- go.mod | 71 ++--- go.sum | 194 +++++++------- internal/acctest/client.go | 8 +- internal/custommodifier/listdefault.go | 47 ++++ internal/provider/provider.go | 4 +- internal/resources/api_key/model.go | 2 +- internal/resources/api_key/resource.go | 10 +- internal/resources/api_key/resource_test.go | 41 +++ .../api_key/test_resources/create.tf | 7 + internal/resources/app_definition/model.go | 42 +-- internal/resources/app_definition/resource.go | 38 +-- .../resources/app_definition/resource_test.go | 25 +- .../resources/app_installation/resource.go | 8 +- internal/resources/contenttype/model.go | 103 ++++---- internal/resources/contenttype/resource.go | 175 ++++--------- .../resources/contenttype/resource_test.go | 79 ++++-- .../test_resources/changed_order.tf | 1 + .../contenttype/test_resources/create.tf | 1 + .../contenttype/test_resources/link_config.tf | 2 + .../contenttype/test_resources/update.tf | 1 + .../test_resources/update_duplicate_field.tf | 34 +++ internal/utils/container.go | 4 +- internal/utils/hcl.go | 8 +- 40 files changed, 830 insertions(+), 696 deletions(-) create mode 100644 .changes/unreleased/Added-20240306-110007.yaml create mode 100644 .changes/unreleased/Added-20240306-110048.yaml create mode 100644 .changes/unreleased/Changed-20240306-105943.yaml create mode 100644 internal/custommodifier/listdefault.go create mode 100644 internal/resources/contenttype/test_resources/update_duplicate_field.tf diff --git a/.changes/unreleased/Added-20240306-110007.yaml b/.changes/unreleased/Added-20240306-110007.yaml new file mode 100644 index 0000000..8594c0c --- /dev/null +++ b/.changes/unreleased/Added-20240306-110007.yaml @@ -0,0 +1,3 @@ +kind: Added +body: added for content types unique validation +time: 2024-03-06T11:00:07.863547+01:00 diff --git a/.changes/unreleased/Added-20240306-110048.yaml b/.changes/unreleased/Added-20240306-110048.yaml new file mode 100644 index 0000000..a3a09da --- /dev/null +++ b/.changes/unreleased/Added-20240306-110048.yaml @@ -0,0 +1,3 @@ +kind: Added +body: switch to latest version of the contentful go lib +time: 2024-03-06T11:00:48.116188+01:00 diff --git a/.changes/unreleased/Changed-20240306-105943.yaml b/.changes/unreleased/Changed-20240306-105943.yaml new file mode 100644 index 0000000..577ea9c --- /dev/null +++ b/.changes/unreleased/Changed-20240306-105943.yaml @@ -0,0 +1,3 @@ +kind: Changed +body: environment for content type is now required +time: 2024-03-06T10:59:43.318104+01:00 diff --git a/contentful/provider.go b/contentful/provider.go index 0b91e79..75e91eb 100644 --- a/contentful/provider.go +++ b/contentful/provider.go @@ -3,6 +3,9 @@ package contentful import ( "context" "github.com/flaconi/contentful-go" + client2 "github.com/flaconi/contentful-go/pkgs/client" + "github.com/flaconi/contentful-go/pkgs/util" + "github.com/flaconi/terraform-provider-contentful/internal/utils" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) @@ -48,9 +51,28 @@ func providerConfigure(_ context.Context, d *schema.ResourceData) (interface{}, cma := contentful.NewCMA(d.Get("cma_token").(string)) cma.SetOrganization(d.Get("organization_id").(string)) + debug := false + if logBoolean != "" { cma.Debug = true + debug = true + } + + client, err := contentful.NewCMAV2(client2.ClientConfig{ + Debug: debug, + UserAgent: util.ToPointer("terraform-provider-contentful"), + Token: d.Get("cma_token").(string), + }) + + if err != nil { + return nil, diag.FromErr(err) + } + + data := utils.ProviderData{ + Client: cma, + CMAClient: client, + OrganizationId: d.Get("organization_id").(string), } - return cma, nil + return data, nil } diff --git a/contentful/resource_contentful_asset.go b/contentful/resource_contentful_asset.go index 3150fd3..bf201ae 100644 --- a/contentful/resource_contentful_asset.go +++ b/contentful/resource_contentful_asset.go @@ -1,10 +1,13 @@ package contentful import ( + "context" "fmt" + "github.com/flaconi/contentful-go/pkgs/common" + "github.com/flaconi/contentful-go/pkgs/model" + "github.com/flaconi/terraform-provider-contentful/internal/utils" "time" - contentful "github.com/flaconi/contentful-go" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) @@ -24,10 +27,6 @@ func resourceContentfulAsset() *schema.Resource { Type: schema.TypeInt, Computed: true, }, - "locale": { - Type: schema.TypeString, - Required: true, - }, "space_id": { Type: schema.TypeString, Required: true, @@ -75,6 +74,10 @@ func resourceContentfulAsset() *schema.Resource { MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ + "locale": { + Type: schema.TypeString, + Required: true, + }, "url": { Type: schema.TypeString, Computed: true, @@ -133,6 +136,10 @@ func resourceContentfulAsset() *schema.Resource { Type: schema.TypeBool, Required: true, }, + "environment": { + Type: schema.TypeString, + Required: true, + }, "archived": { Type: schema.TypeBool, Required: true, @@ -142,75 +149,63 @@ func resourceContentfulAsset() *schema.Resource { } func resourceCreateAsset(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Client) + client := m.(utils.ProviderData).CMAClient + spaceID := d.Get("space_id").(string) - fields := d.Get("fields").([]interface{})[0].(map[string]interface{}) + assetClient := client.WithSpaceId(spaceID).WithEnvironment(d.Get("environment").(string)).Assets() - localizedTitle := map[string]string{} - rawTitle := fields["title"].([]interface{}) - for i := 0; i < len(rawTitle); i++ { - field := rawTitle[i].(map[string]interface{}) - localizedTitle[field["locale"].(string)] = field["content"].(string) - } + asset, err := buildAsset(d) - localizedDescription := map[string]string{} - rawDescription := fields["description"].([]interface{}) - for i := 0; i < len(rawDescription); i++ { - field := rawDescription[i].(map[string]interface{}) - localizedDescription[field["locale"].(string)] = field["content"].(string) + if err != nil { + return err } - files := fields["file"].([]interface{}) + if err = assetClient.Upsert(context.Background(), asset); err != nil { + return err + } - if len(files) == 0 { - return fmt.Errorf("file block not defined in asset") + if err = assetClient.Process(context.Background(), asset); err != nil { + return err } - file := files[0].(map[string]interface{}) + d.SetId(asset.Sys.ID) - asset := &contentful.Asset{ - Sys: &contentful.Sys{ - ID: d.Get("asset_id").(string), - Version: 0, - }, - Locale: d.Get("locale").(string), - Fields: &contentful.AssetFields{ - Title: localizedTitle, - Description: localizedDescription, - File: map[string]*contentful.File{ - d.Get("locale").(string): { - FileName: file["file_name"].(string), - ContentType: file["content_type"].(string), - }, - }, - }, + if err := setAssetProperties(d, asset); err != nil { + return err } - if url, ok := file["url"].(string); ok && url != "" { - asset.Fields.File[d.Get("locale").(string)].URL = url - } + time.Sleep(1 * time.Second) // avoid race conditions with version mismatches - if upload, ok := file["upload"].(string); ok && upload != "" { - asset.Fields.File[d.Get("locale").(string)].UploadURL = upload + if err = setAssetState(d, m); err != nil { + return err } - if details, ok := file["file_details"].(*contentful.FileDetails); ok { - asset.Fields.File[d.Get("locale").(string)].Details = details + return err +} + +func resourceUpdateAsset(d *schema.ResourceData, m interface{}) (err error) { + client := m.(utils.ProviderData).CMAClient + spaceID := d.Get("space_id").(string) + assetID := d.Id() + + assetClient := client.WithSpaceId(spaceID).WithEnvironment(d.Get("environment").(string)).Assets() + + _, err = assetClient.Get(context.Background(), assetID) + if err != nil { + return err } - if uploadFrom, ok := file["upload_from"].(string); ok && uploadFrom != "" { - asset.Fields.File[d.Get("locale").(string)].UploadFrom = &contentful.UploadFrom{ - Sys: &contentful.Sys{ - ID: uploadFrom, - }, - } + asset, err := buildAsset(d) + + if err != nil { + return err } - if err = client.Assets.Upsert(d.Get("space_id").(string), asset); err != nil { + if err := assetClient.Upsert(context.Background(), asset); err != nil { return err } - if err = client.Assets.Process(d.Get("space_id").(string), asset); err != nil { + if err = assetClient.Process(context.Background(), asset); err != nil { return err } @@ -220,8 +215,6 @@ func resourceCreateAsset(d *schema.ResourceData, m interface{}) (err error) { return err } - time.Sleep(1 * time.Second) // avoid race conditions with version mismatches - if err = setAssetState(d, m); err != nil { return err } @@ -229,16 +222,7 @@ func resourceCreateAsset(d *schema.ResourceData, m interface{}) (err error) { return err } -func resourceUpdateAsset(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Client) - spaceID := d.Get("space_id").(string) - assetID := d.Id() - - _, err = client.Assets.Get(spaceID, assetID) - if err != nil { - return err - } - +func buildAsset(d *schema.ResourceData) (*model.Asset, error) { fields := d.Get("fields").([]interface{})[0].(map[string]interface{}) localizedTitle := map[string]string{} @@ -258,93 +242,92 @@ func resourceUpdateAsset(d *schema.ResourceData, m interface{}) (err error) { files := fields["file"].([]interface{}) if len(files) == 0 { - return fmt.Errorf("file block not defined in asset") - } - - file := files[0].(map[string]interface{}) - - asset := &contentful.Asset{ - Sys: &contentful.Sys{ - ID: d.Get("asset_id").(string), - Version: d.Get("version").(int), - }, - Locale: d.Get("locale").(string), - Fields: &contentful.AssetFields{ - Title: localizedTitle, - Description: localizedDescription, - File: map[string]*contentful.File{ - d.Get("locale").(string): { - FileName: file["file_name"].(string), - ContentType: file["content_type"].(string), - }, - }, - }, + return nil, fmt.Errorf("file block not defined in asset") } - if url, ok := file["url"].(string); ok && url != "" { - asset.Fields.File[d.Get("locale").(string)].URL = url - } - - if upload, ok := file["upload"].(string); ok && upload != "" { - asset.Fields.File[d.Get("locale").(string)].UploadURL = upload - } + fileData := map[string]*model.File{} + for _, file := range files { + fileLocale := file.(map[string]any) - if details, ok := file["file_details"].(*contentful.FileDetails); ok { - asset.Fields.File[d.Get("locale").(string)].Details = details - } - - if uploadFrom, ok := file["upload_from"].(string); ok && uploadFrom != "" { - asset.Fields.File[d.Get("locale").(string)].UploadFrom = &contentful.UploadFrom{ - Sys: &contentful.Sys{ - ID: uploadFrom, - }, + fileData[fileLocale["locale"].(string)] = &model.File{ + URL: "", + UploadURL: "", + UploadFrom: nil, + Details: nil, + FileName: fileLocale["file_name"].(string), + ContentType: fileLocale["content_type"].(string), } - } - if err := client.Assets.Upsert(d.Get("space_id").(string), asset); err != nil { - return err - } + if url, ok := fileLocale["url"].(string); ok && url != "" { + fileData[fileLocale["locale"].(string)].URL = url + } - if err = client.Assets.Process(d.Get("space_id").(string), asset); err != nil { - return err - } + if upload, ok := fileLocale["upload"].(string); ok && upload != "" { + fileData[fileLocale["locale"].(string)].UploadURL = upload + } - d.SetId(asset.Sys.ID) + if details, ok := fileLocale["file_details"].(*model.FileDetails); ok { + fileData[fileLocale["locale"].(string)].Details = details + } - if err := setAssetProperties(d, asset); err != nil { - return err - } + if uploadFrom, ok := fileLocale["upload_from"].(string); ok && uploadFrom != "" { + fileData[fileLocale["locale"].(string)].UploadFrom = &model.UploadFrom{ + Sys: &model.BaseSys{ + ID: uploadFrom, + }, + } + } - if err = setAssetState(d, m); err != nil { - return err } - return err + return &model.Asset{ + Sys: &model.PublishSys{ + EnvironmentSys: model.EnvironmentSys{ + SpaceSys: model.SpaceSys{ + CreatedSys: model.CreatedSys{ + BaseSys: model.BaseSys{ + ID: d.Get("asset_id").(string), + Version: d.Get("version").(int), + }, + }, + }, + }, + }, + Fields: &model.AssetFields{ + Title: localizedTitle, + Description: localizedDescription, + File: fileData, + }, + }, nil } func setAssetState(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Client) + client := m.(utils.ProviderData).CMAClient spaceID := d.Get("space_id").(string) assetID := d.Id() - asset, _ := client.Assets.Get(spaceID, assetID) + assetClient := client.WithSpaceId(spaceID).WithEnvironment(d.Get("environment").(string)).Assets() + + ctx := context.Background() + + asset, _ := assetClient.Get(ctx, assetID) if d.Get("published").(bool) && asset.Sys.PublishedAt == "" { - if err = client.Assets.Publish(spaceID, asset); err != nil { + if err = assetClient.Publish(ctx, asset); err != nil { return err } } else if !d.Get("published").(bool) && asset.Sys.PublishedAt != "" { - if err = client.Assets.Unpublish(spaceID, asset); err != nil { + if err = assetClient.Unpublish(ctx, asset); err != nil { return err } } if d.Get("archived").(bool) && asset.Sys.ArchivedAt == "" { - if err = client.Assets.Archive(spaceID, asset); err != nil { + if err = assetClient.Archive(ctx, asset); err != nil { return err } } else if !d.Get("archived").(bool) && asset.Sys.ArchivedAt != "" { - if err = client.Assets.Unarchive(spaceID, asset); err != nil { + if err = assetClient.Unarchive(ctx, asset); err != nil { return err } } @@ -354,12 +337,14 @@ func setAssetState(d *schema.ResourceData, m interface{}) (err error) { } func resourceReadAsset(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Client) + client := m.(utils.ProviderData).CMAClient spaceID := d.Get("space_id").(string) assetID := d.Id() - asset, err := client.Assets.Get(spaceID, assetID) - if _, ok := err.(contentful.NotFoundError); ok { + assetClient := client.WithSpaceId(spaceID).WithEnvironment(d.Get("environment").(string)).Assets() + + asset, err := assetClient.Get(context.Background(), assetID) + if _, ok := err.(common.NotFoundError); ok { d.SetId("") return nil } @@ -368,19 +353,21 @@ func resourceReadAsset(d *schema.ResourceData, m interface{}) (err error) { } func resourceDeleteAsset(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Client) + client := m.(utils.ProviderData).CMAClient spaceID := d.Get("space_id").(string) assetID := d.Id() - asset, err := client.Assets.Get(spaceID, assetID) + assetClient := client.WithSpaceId(spaceID).WithEnvironment(d.Get("environment").(string)).Assets() + + asset, err := assetClient.Get(context.Background(), assetID) if err != nil { return err } - return client.Assets.Delete(spaceID, asset) + return assetClient.Delete(context.Background(), asset) } -func setAssetProperties(d *schema.ResourceData, asset *contentful.Asset) (err error) { +func setAssetProperties(d *schema.ResourceData, asset *model.Asset) (err error) { if err = d.Set("space_id", asset.Sys.Space.Sys.ID); err != nil { return err } diff --git a/contentful/resource_contentful_asset_test.go b/contentful/resource_contentful_asset_test.go index 7c81313..6beffc3 100644 --- a/contentful/resource_contentful_asset_test.go +++ b/contentful/resource_contentful_asset_test.go @@ -1,16 +1,18 @@ package contentful import ( + "context" "fmt" + "github.com/flaconi/contentful-go/pkgs/model" + "github.com/flaconi/terraform-provider-contentful/internal/acctest" "testing" - contentful "github.com/flaconi/contentful-go" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" ) func TestAccContentfulAsset_Basic(t *testing.T) { - var asset contentful.Asset + var asset model.Asset resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -39,7 +41,7 @@ func TestAccContentfulAsset_Basic(t *testing.T) { }) } -func testAccCheckContentfulAssetExists(n string, asset *contentful.Asset) resource.TestCheckFunc { +func testAccCheckContentfulAssetExists(n string, asset *model.Asset) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] if !ok { @@ -51,9 +53,9 @@ func testAccCheckContentfulAssetExists(n string, asset *contentful.Asset) resour return fmt.Errorf("no space_id is set") } - client := testAccProvider.Meta().(*contentful.Client) + client := acctest.GetCMA() - contentfulAsset, err := client.Assets.Get(spaceID, rs.Primary.ID) + contentfulAsset, err := client.WithSpaceId(spaceID).WithEnvironment("master").Assets().Get(context.Background(), rs.Primary.ID) if err != nil { return err } @@ -64,7 +66,7 @@ func testAccCheckContentfulAssetExists(n string, asset *contentful.Asset) resour } } -func testAccCheckContentfulAssetAttributes(asset *contentful.Asset, attrs map[string]interface{}) resource.TestCheckFunc { +func testAccCheckContentfulAssetAttributes(asset *model.Asset, attrs map[string]interface{}) resource.TestCheckFunc { return func(s *terraform.State) error { spaceIDCheck := attrs["space_id"].(string) @@ -94,9 +96,9 @@ func testAccContentfulAssetDestroy(s *terraform.State) error { } // sdk client - client := testAccProvider.Meta().(*contentful.Client) + client := acctest.GetCMA() - asset, _ := client.Assets.Get(spaceID, rs.Primary.ID) + asset, _ := client.WithSpaceId(spaceID).WithEnvironment("master").Assets().Get(context.Background(), rs.Primary.ID) if asset == nil { return nil } @@ -110,7 +112,8 @@ func testAccContentfulAssetDestroy(s *terraform.State) error { var testAccContentfulAssetConfig = ` resource "contentful_asset" "myasset" { asset_id = "test_asset" - locale = "en-US" + + environment = "master" space_id = "` + spaceID + `" fields { title { @@ -125,6 +128,7 @@ resource "contentful_asset" "myasset" { upload = "https://images.ctfassets.net/fo9twyrwpveg/2VQx7vz73aMEYi20MMgCk0/66e502115b1f1f973a944b4bd2cc536f/IC-1H_Modern_Stack_Website.svg" file_name = "example.jpeg" content_type = "image/jpeg" + locale = "en-US" } } published = true @@ -135,7 +139,7 @@ resource "contentful_asset" "myasset" { var testAccContentfulAssetUpdateConfig = ` resource "contentful_asset" "myasset" { asset_id = "test_asset" - locale = "en-US" + environment = "master" space_id = "` + spaceID + `" fields { title { @@ -150,6 +154,7 @@ resource "contentful_asset" "myasset" { upload = "https://images.ctfassets.net/fo9twyrwpveg/2VQx7vz73aMEYi20MMgCk0/66e502115b1f1f973a944b4bd2cc536f/IC-1H_Modern_Stack_Website.svg" file_name = "example.jpeg" content_type = "image/jpeg" + locale = "en-US" } } published = false diff --git a/contentful/resource_contentful_entry.go b/contentful/resource_contentful_entry.go index 1911017..b2960f4 100644 --- a/contentful/resource_contentful_entry.go +++ b/contentful/resource_contentful_entry.go @@ -1,7 +1,10 @@ package contentful import ( - contentful "github.com/flaconi/contentful-go" + "context" + "github.com/flaconi/contentful-go/pkgs/common" + "github.com/flaconi/contentful-go/pkgs/model" + "github.com/flaconi/terraform-provider-contentful/internal/utils" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) @@ -25,11 +28,11 @@ func resourceContentfulEntry() *schema.Resource { Type: schema.TypeString, Required: true, }, - "contenttype_id": { + "environment": { Type: schema.TypeString, Required: true, }, - "locale": { + "contenttype_id": { Type: schema.TypeString, Required: true, }, @@ -66,7 +69,7 @@ func resourceContentfulEntry() *schema.Resource { } func resourceCreateEntry(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Client) + client := m.(utils.ProviderData).CMAClient fieldProperties := map[string]interface{}{} rawField := d.Get("field").([]interface{}) @@ -76,15 +79,22 @@ func resourceCreateEntry(d *schema.ResourceData, m interface{}) (err error) { fieldProperties[field["id"].(string)].(map[string]interface{})[field["locale"].(string)] = field["content"].(string) } - entry := &contentful.Entry{ - Locale: d.Get("locale").(string), + entry := &model.Entry{ Fields: fieldProperties, - Sys: &contentful.Sys{ - ID: d.Get("entry_id").(string), + Sys: &model.PublishSys{ + EnvironmentSys: model.EnvironmentSys{ + SpaceSys: model.SpaceSys{ + CreatedSys: model.CreatedSys{ + BaseSys: model.BaseSys{ + ID: d.Get("entry_id").(string), + }, + }, + }, + }, }, } - err = client.Entries.Upsert(d.Get("space_id").(string), d.Get("contenttype_id").(string), entry) + err = client.WithSpaceId(d.Get("space_id").(string)).WithEnvironment(d.Get("environment").(string)).Entries().Upsert(context.Background(), d.Get("contenttype_id").(string), entry) if err != nil { return err } @@ -103,11 +113,13 @@ func resourceCreateEntry(d *schema.ResourceData, m interface{}) (err error) { } func resourceUpdateEntry(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Client) + client := m.(utils.ProviderData).CMAClient spaceID := d.Get("space_id").(string) entryID := d.Id() - entry, err := client.Entries.Get(spaceID, entryID) + entryClient := client.WithSpaceId(spaceID).WithEnvironment(d.Get("environment").(string)).Entries() + + entry, err := entryClient.Get(context.Background(), entryID) if err != nil { return err } @@ -121,9 +133,8 @@ func resourceUpdateEntry(d *schema.ResourceData, m interface{}) (err error) { } entry.Fields = fieldProperties - entry.Locale = d.Get("locale").(string) - err = client.Entries.Upsert(d.Get("space_id").(string), d.Get("contenttype_id").(string), entry) + err = entryClient.Upsert(context.Background(), d.Get("contenttype_id").(string), entry) if err != nil { return err } @@ -142,34 +153,36 @@ func resourceUpdateEntry(d *schema.ResourceData, m interface{}) (err error) { } func setEntryState(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Client) + client := m.(utils.ProviderData).CMAClient spaceID := d.Get("space_id").(string) entryID := d.Id() - entry, _ := client.Entries.Get(spaceID, entryID) + entryClient := client.WithSpaceId(spaceID).WithEnvironment(d.Get("environment").(string)).Entries() + + entry, _ := entryClient.Get(context.Background(), entryID) if d.Get("published").(bool) && entry.Sys.PublishedAt == "" { - err = client.Entries.Publish(spaceID, entry) + err = entryClient.Publish(context.Background(), entry) } else if !d.Get("published").(bool) && entry.Sys.PublishedAt != "" { - err = client.Entries.Unpublish(spaceID, entry) + err = entryClient.Unpublish(context.Background(), entry) } if d.Get("archived").(bool) && entry.Sys.ArchivedAt == "" { - err = client.Entries.Archive(spaceID, entry) + err = entryClient.Archive(context.Background(), entry) } else if !d.Get("archived").(bool) && entry.Sys.ArchivedAt != "" { - err = client.Entries.Unarchive(spaceID, entry) + err = entryClient.Unarchive(context.Background(), entry) } return err } func resourceReadEntry(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Client) + client := m.(utils.ProviderData).CMAClient spaceID := d.Get("space_id").(string) entryID := d.Id() - entry, err := client.Entries.Get(spaceID, entryID) - if _, ok := err.(contentful.NotFoundError); ok { + entry, err := client.WithSpaceId(spaceID).WithEnvironment(d.Get("environment").(string)).Entries().Get(context.Background(), entryID) + if _, ok := err.(common.NotFoundError); ok { d.SetId("") return nil } @@ -178,19 +191,21 @@ func resourceReadEntry(d *schema.ResourceData, m interface{}) (err error) { } func resourceDeleteEntry(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Client) + client := m.(utils.ProviderData).CMAClient spaceID := d.Get("space_id").(string) entryID := d.Id() - _, err = client.Entries.Get(spaceID, entryID) + entryClient := client.WithSpaceId(spaceID).WithEnvironment(d.Get("environment").(string)).Entries() + + entry, err := entryClient.Get(context.Background(), entryID) if err != nil { return err } - return client.Entries.Delete(spaceID, entryID) + return entryClient.Delete(context.Background(), entry) } -func setEntryProperties(d *schema.ResourceData, entry *contentful.Entry) (err error) { +func setEntryProperties(d *schema.ResourceData, entry *model.Entry) (err error) { if err = d.Set("space_id", entry.Sys.Space.Sys.ID); err != nil { return err } diff --git a/contentful/resource_contentful_entry_test.go b/contentful/resource_contentful_entry_test.go index def2c2a..dee7ed6 100644 --- a/contentful/resource_contentful_entry_test.go +++ b/contentful/resource_contentful_entry_test.go @@ -1,16 +1,21 @@ package contentful import ( + "context" "fmt" + "github.com/flaconi/contentful-go/pkgs/model" + "github.com/flaconi/terraform-provider-contentful/internal/acctest" + "os" "testing" - contentful "github.com/flaconi/contentful-go" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" ) func TestAccContentfulEntry_Basic(t *testing.T) { - var entry contentful.Entry + //todo remove skip when entry is moved to new sdk style as content type already moved + t.Skip() + var entry model.Entry resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -39,7 +44,7 @@ func TestAccContentfulEntry_Basic(t *testing.T) { }) } -func testAccCheckContentfulEntryExists(n string, entry *contentful.Entry) resource.TestCheckFunc { +func testAccCheckContentfulEntryExists(n string, entry *model.Entry) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] if !ok { @@ -56,9 +61,9 @@ func testAccCheckContentfulEntryExists(n string, entry *contentful.Entry) resour return fmt.Errorf("no contenttype_id is set") } - client := testAccProvider.Meta().(*contentful.Client) + client := acctest.GetCMA() - contentfulEntry, err := client.Entries.Get(spaceID, rs.Primary.ID) + contentfulEntry, err := client.WithSpaceId(os.Getenv("CONTENTFUL_SPACE_ID")).WithEnvironment("master").Entries().Get(context.Background(), rs.Primary.ID) if err != nil { return err } @@ -69,7 +74,7 @@ func testAccCheckContentfulEntryExists(n string, entry *contentful.Entry) resour } } -func testAccCheckContentfulEntryAttributes(entry *contentful.Entry, attrs map[string]interface{}) resource.TestCheckFunc { +func testAccCheckContentfulEntryAttributes(entry *model.Entry, attrs map[string]interface{}) resource.TestCheckFunc { return func(s *terraform.State) error { spaceIDCheck := attrs["space_id"].(string) @@ -99,9 +104,9 @@ func testAccContentfulEntryDestroy(s *terraform.State) error { } // sdk client - client := testAccProvider.Meta().(*contentful.Client) + client := acctest.GetCMA() - entry, _ := client.Entries.Get(spaceID, rs.Primary.ID) + entry, _ := client.WithSpaceId(os.Getenv("CONTENTFUL_SPACE_ID")).WithEnvironment("master").Entries().Get(context.Background(), rs.Primary.ID) if entry == nil { return nil } @@ -116,6 +121,7 @@ var testAccContentfulEntryConfig = ` resource "contentful_contenttype" "mycontenttype" { space_id = "` + spaceID + `" name = "tf_test_1" + environment = "master" description = "Terraform Acc Test Content Type" display_field = "field1" field { @@ -141,6 +147,7 @@ resource "contentful_contenttype" "mycontenttype" { resource "contentful_entry" "myentry" { entry_id = "mytestentry" space_id = "` + spaceID + `" + environment = "master" contenttype_id = "tf_test_1" locale = "en-US" field { @@ -162,6 +169,7 @@ resource "contentful_entry" "myentry" { var testAccContentfulEntryUpdateConfig = ` resource "contentful_contenttype" "mycontenttype" { space_id = "` + spaceID + `" + environment = "master" name = "tf_test_1" description = "Terraform Acc Test Content Type" display_field = "field1" @@ -188,6 +196,7 @@ resource "contentful_contenttype" "mycontenttype" { resource "contentful_entry" "myentry" { entry_id = "mytestentry" space_id = "` + spaceID + `" + environment = "master" contenttype_id = "tf_test_1" locale = "en-US" field { diff --git a/contentful/resource_contentful_environment.go b/contentful/resource_contentful_environment.go index ae4060f..40ca788 100644 --- a/contentful/resource_contentful_environment.go +++ b/contentful/resource_contentful_environment.go @@ -1,7 +1,10 @@ package contentful import ( - contentful "github.com/flaconi/contentful-go" + "context" + "github.com/flaconi/contentful-go/pkgs/common" + "github.com/flaconi/contentful-go/pkgs/model" + "github.com/flaconi/terraform-provider-contentful/internal/utils" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) @@ -30,13 +33,13 @@ func resourceContentfulEnvironment() *schema.Resource { } func resourceCreateEnvironment(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Client) + client := m.(utils.ProviderData).CMAClient - environment := &contentful.Environment{ + environment := &model.Environment{ Name: d.Get("name").(string), } - err = client.Environments.Upsert(d.Get("space_id").(string), environment) + err = client.WithSpaceId(spaceID).Environments().Upsert(context.Background(), environment, nil) if err != nil { return err } @@ -51,18 +54,20 @@ func resourceCreateEnvironment(d *schema.ResourceData, m interface{}) (err error } func resourceUpdateEnvironment(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Client) + client := m.(utils.ProviderData).CMAClient spaceID := d.Get("space_id").(string) environmentID := d.Id() - environment, err := client.Environments.Get(spaceID, environmentID) + envClient := client.WithSpaceId(spaceID).Environments() + + environment, err := envClient.Get(context.Background(), environmentID) if err != nil { return err } environment.Name = d.Get("name").(string) - err = client.Environments.Upsert(spaceID, environment) + err = envClient.Upsert(context.Background(), environment, nil) if err != nil { return err } @@ -77,12 +82,12 @@ func resourceUpdateEnvironment(d *schema.ResourceData, m interface{}) (err error } func resourceReadEnvironment(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Client) + client := m.(utils.ProviderData).CMAClient spaceID := d.Get("space_id").(string) environmentID := d.Id() - environment, err := client.Environments.Get(spaceID, environmentID) - if _, ok := err.(contentful.NotFoundError); ok { + environment, err := client.WithSpaceId(spaceID).Environments().Get(context.Background(), environmentID) + if _, ok := err.(common.NotFoundError); ok { d.SetId("") return nil } @@ -91,19 +96,21 @@ func resourceReadEnvironment(d *schema.ResourceData, m interface{}) (err error) } func resourceDeleteEnvironment(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Client) + client := m.(utils.ProviderData).CMAClient spaceID := d.Get("space_id").(string) environmentID := d.Id() - environment, err := client.Environments.Get(spaceID, environmentID) + envClient := client.WithSpaceId(spaceID).Environments() + + environment, err := envClient.Get(context.Background(), environmentID) if err != nil { return err } - return client.Environments.Delete(spaceID, environment) + return envClient.Delete(context.Background(), environment) } -func setEnvironmentProperties(d *schema.ResourceData, environment *contentful.Environment) error { +func setEnvironmentProperties(d *schema.ResourceData, environment *model.Environment) error { if err := d.Set("space_id", environment.Sys.Space.Sys.ID); err != nil { return err } diff --git a/contentful/resource_contentful_environment_test.go b/contentful/resource_contentful_environment_test.go index 0624afe..6dfe2bb 100644 --- a/contentful/resource_contentful_environment_test.go +++ b/contentful/resource_contentful_environment_test.go @@ -1,16 +1,20 @@ package contentful import ( + "context" "fmt" + "github.com/flaconi/contentful-go/pkgs/common" + "github.com/flaconi/contentful-go/pkgs/model" + "github.com/flaconi/terraform-provider-contentful/internal/acctest" + "os" "testing" - contentful "github.com/flaconi/contentful-go" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" ) func TestAccContentfulEnvironment_Basic(t *testing.T) { - var environment contentful.Environment + var environment model.Environment resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -41,7 +45,7 @@ func TestAccContentfulEnvironment_Basic(t *testing.T) { }) } -func testAccCheckContentfulEnvironmentExists(n string, environment *contentful.Environment) resource.TestCheckFunc { +func testAccCheckContentfulEnvironmentExists(n string, environment *model.Environment) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] if !ok { @@ -58,9 +62,10 @@ func testAccCheckContentfulEnvironmentExists(n string, environment *contentful.E return fmt.Errorf("no name is set") } - client := testAccProvider.Meta().(*contentful.Client) + client := acctest.GetCMA() + + contentfulEnvironment, err := client.WithSpaceId(os.Getenv("CONTENTFUL_SPACE_ID")).Environments().Get(context.Background(), rs.Primary.ID) - contentfulEnvironment, err := client.Environments.Get(spaceID, rs.Primary.ID) if err != nil { return err } @@ -71,11 +76,11 @@ func testAccCheckContentfulEnvironmentExists(n string, environment *contentful.E } } -func testAccCheckContentfulEnvironmentAttributes(environment *contentful.Environment, attrs map[string]interface{}) resource.TestCheckFunc { +func testAccCheckContentfulEnvironmentAttributes(environment *model.Environment, attrs map[string]interface{}) resource.TestCheckFunc { return func(s *terraform.State) error { name := attrs["name"].(string) if environment.Name != name { - return fmt.Errorf("locale name does not match: %s, %s", environment.Name, name) + return fmt.Errorf("environment name does not match: %s, %s", environment.Name, name) } return nil @@ -84,7 +89,7 @@ func testAccCheckContentfulEnvironmentAttributes(environment *contentful.Environ func testAccContentfulEnvironmentDestroy(s *terraform.State) error { for _, rs := range s.RootModule().Resources { - if rs.Type != "contentful_locale" { + if rs.Type != "contentful_environment" { continue } spaceID := rs.Primary.Attributes["space_id"] @@ -92,19 +97,20 @@ func testAccContentfulEnvironmentDestroy(s *terraform.State) error { return fmt.Errorf("no space_id is set") } - localeID := rs.Primary.ID - if localeID == "" { - return fmt.Errorf("no locale ID is set") + environmentID := rs.Primary.ID + if environmentID == "" { + return fmt.Errorf("no environment ID is set") } - client := testAccProvider.Meta().(*contentful.Client) + client := acctest.GetCMA() + + _, err := client.WithSpaceId(os.Getenv("CONTENTFUL_SPACE_ID")).Environments().Get(context.Background(), environmentID) - _, err := client.Locales.Get(spaceID, localeID) - if _, ok := err.(contentful.NotFoundError); ok { + if _, ok := err.(common.NotFoundError); ok { return nil } - return fmt.Errorf("locale still exists with id: %s", localeID) + return fmt.Errorf("environment still exists with id: %s", environmentID) } return nil diff --git a/contentful/resource_contentful_locale.go b/contentful/resource_contentful_locale.go index 2609730..6941cb6 100644 --- a/contentful/resource_contentful_locale.go +++ b/contentful/resource_contentful_locale.go @@ -4,7 +4,10 @@ import ( "context" "errors" "fmt" - "github.com/flaconi/contentful-go" + "github.com/flaconi/contentful-go/pkgs/common" + "github.com/flaconi/contentful-go/pkgs/model" + "github.com/flaconi/contentful-go/service/cma" + "github.com/flaconi/terraform-provider-contentful/internal/utils" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "strings" @@ -87,18 +90,19 @@ func resourceContentfulLocale() *schema.Resource { }, "environment": { Type: schema.TypeString, - Optional: true, + Required: true, }, }, } } func resourceCreateLocale(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - client := m.(*contentful.Client) + client := m.(utils.ProviderData).CMAClient spaceID := d.Get("space_id").(string) + localesClient := client.WithSpaceId(spaceID).WithEnvironment(d.Get("environment").(string)).Locales() var err error - locale := &contentful.Locale{ + locale := &model.Locale{ Name: d.Get("name").(string), Code: d.Get("code").(string), FallbackCode: nil, @@ -114,18 +118,7 @@ func resourceCreateLocale(_ context.Context, d *schema.ResourceData, m interface locale.FallbackCode = &fallbackCodeStr } - if environment, ok := d.GetOk("environment"); ok { - - env, envErr := client.Environments.Get(spaceID, environment.(string)) - - if envErr != nil { - return diag.FromErr(envErr) - } - - err = client.Locales.UpsertWithEnv(env, locale) - } else { - err = client.Locales.Upsert(spaceID, locale) - } + err = localesClient.Upsert(context.Background(), locale) if err != nil { return diag.FromErr(err) @@ -142,11 +135,13 @@ func resourceCreateLocale(_ context.Context, d *schema.ResourceData, m interface } func resourceReadLocale(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - client := m.(*contentful.Client) + client := m.(utils.ProviderData).CMAClient + spaceID := d.Get("space_id").(string) + localesClient := client.WithSpaceId(spaceID).WithEnvironment(d.Get("environment").(string)).Locales() - locale, err := getLocale(d, client) + locale, err := getLocale(d, localesClient) - var notFoundError *contentful.NotFoundError + var notFoundError *common.NotFoundError if errors.As(err, ¬FoundError) { d.SetId("") return nil @@ -160,10 +155,11 @@ func resourceReadLocale(_ context.Context, d *schema.ResourceData, m interface{} } func resourceUpdateLocale(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - client := m.(*contentful.Client) + client := m.(utils.ProviderData).CMAClient spaceID := d.Get("space_id").(string) + localesClient := client.WithSpaceId(spaceID).WithEnvironment(d.Get("environment").(string)).Locales() - locale, err := getLocale(d, client) + locale, err := getLocale(d, localesClient) if err != nil { return diag.FromErr(err) @@ -185,18 +181,7 @@ func resourceUpdateLocale(_ context.Context, d *schema.ResourceData, m interface locale.CDA = d.Get("cda").(bool) locale.CMA = d.Get("cma").(bool) - if environment, ok := d.GetOk("environment"); ok { - env, envErr := client.Environments.Get(spaceID, environment.(string)) - - if envErr != nil { - return diag.FromErr(envErr) - } - - err = client.Locales.UpsertWithEnv(env, locale) - - } else { - err = client.Locales.Upsert(spaceID, locale) - } + err = localesClient.Upsert(context.Background(), locale) if err != nil { return diag.FromErr(err) @@ -206,29 +191,19 @@ func resourceUpdateLocale(_ context.Context, d *schema.ResourceData, m interface } func resourceDeleteLocale(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - client := m.(*contentful.Client) + client := m.(utils.ProviderData).CMAClient spaceID := d.Get("space_id").(string) + localesClient := client.WithSpaceId(spaceID).WithEnvironment(d.Get("environment").(string)).Locales() - locale, err := getLocale(d, client) + locale, err := getLocale(d, localesClient) if err != nil { return diag.FromErr(err) } - if environment, ok := d.GetOk("environment"); ok { - env, envErr := client.Environments.Get(spaceID, environment.(string)) - - if envErr != nil { - return diag.FromErr(envErr) - } - - err = client.Locales.DeleteWithEnv(env, locale) - - } else { - err = client.Locales.Delete(spaceID, locale) - } + err = localesClient.Delete(context.Background(), locale) - var notFoundError *contentful.NotFoundError + var notFoundError *common.NotFoundError if errors.As(err, ¬FoundError) { return nil } @@ -240,7 +215,7 @@ func resourceDeleteLocale(_ context.Context, d *schema.ResourceData, m interface return nil } -func setLocaleProperties(d *schema.ResourceData, locale *contentful.Locale) diag.Diagnostics { +func setLocaleProperties(d *schema.ResourceData, locale *model.Locale) diag.Diagnostics { err := d.Set("name", locale.Name) if err != nil { return diag.FromErr(err) @@ -279,17 +254,6 @@ func setLocaleProperties(d *schema.ResourceData, locale *contentful.Locale) diag return nil } -func getLocale(d *schema.ResourceData, client *contentful.Client) (*contentful.Locale, error) { - spaceID := d.Get("space_id").(string) - if environment, ok := d.GetOk("environment"); ok { - env, envErr := client.Environments.Get(spaceID, environment.(string)) - - if envErr != nil { - return nil, envErr - } - - return client.Locales.GetWithEnv(env, d.Id()) - } else { - return client.Locales.Get(spaceID, d.Id()) - } +func getLocale(d *schema.ResourceData, client cma.Locales) (*model.Locale, error) { + return client.Get(context.Background(), d.Id()) } diff --git a/contentful/resource_contentful_locale_test.go b/contentful/resource_contentful_locale_test.go index 910c2ba..515f298 100644 --- a/contentful/resource_contentful_locale_test.go +++ b/contentful/resource_contentful_locale_test.go @@ -1,17 +1,21 @@ package contentful import ( + "context" "errors" "fmt" + "github.com/flaconi/contentful-go/pkgs/common" + "github.com/flaconi/contentful-go/pkgs/model" + "github.com/flaconi/terraform-provider-contentful/internal/acctest" + "os" "testing" - "github.com/flaconi/contentful-go" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" ) func TestAccContentfulLocales_Basic(t *testing.T) { - var locale contentful.Locale + var locale model.Locale resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -52,7 +56,7 @@ func TestAccContentfulLocales_Basic(t *testing.T) { }) } -func testAccCheckContentfulLocaleExists(n string, locale *contentful.Locale) resource.TestCheckFunc { +func testAccCheckContentfulLocaleExists(n string, locale *model.Locale) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] if !ok { @@ -69,9 +73,10 @@ func testAccCheckContentfulLocaleExists(n string, locale *contentful.Locale) res return fmt.Errorf("no locale ID is set") } - client := testAccProvider.Meta().(*contentful.Client) + client := acctest.GetCMA() + + contentfulLocale, err := client.WithSpaceId(os.Getenv("CONTENTFUL_SPACE_ID")).WithEnvironment("master").Locales().Get(context.Background(), localeID) - contentfulLocale, err := client.Locales.Get(spaceID, localeID) if err != nil { return err } @@ -82,7 +87,7 @@ func testAccCheckContentfulLocaleExists(n string, locale *contentful.Locale) res } } -func testAccCheckContentfulLocaleAttributes(locale *contentful.Locale, attrs map[string]interface{}) resource.TestCheckFunc { +func testAccCheckContentfulLocaleAttributes(locale *model.Locale, attrs map[string]interface{}) resource.TestCheckFunc { return func(s *terraform.State) error { name := attrs["name"].(string) if locale.Name != name { @@ -134,11 +139,11 @@ func testAccContentfulLocaleDestroy(s *terraform.State) error { return fmt.Errorf("no locale ID is set") } - client := testAccProvider.Meta().(*contentful.Client) + client := acctest.GetCMA() - _, err := client.Locales.Get(spaceID, localeID) + _, err := client.WithSpaceId(os.Getenv("CONTENTFUL_SPACE_ID")).WithEnvironment("master").Locales().Get(context.Background(), localeID) - var notFoundError contentful.NotFoundError + var notFoundError common.NotFoundError if errors.As(err, ¬FoundError) { return nil } @@ -152,7 +157,7 @@ func testAccContentfulLocaleDestroy(s *terraform.State) error { var testAccContentfulLocaleConfig = ` resource "contentful_locale" "mylocale" { space_id = "` + spaceID + `" - + environment = "master" name = "locale-name" code = "de" fallback_code = "en-US" @@ -165,7 +170,7 @@ resource "contentful_locale" "mylocale" { var testAccContentfulLocaleUpdateConfig = ` resource "contentful_locale" "mylocale" { space_id = "` + spaceID + `" - + environment = "master" name = "locale-name-updated" code = "es" fallback_code = "en-US" diff --git a/contentful/resource_contentful_space.go b/contentful/resource_contentful_space.go index 03acc3d..1070ec6 100644 --- a/contentful/resource_contentful_space.go +++ b/contentful/resource_contentful_space.go @@ -2,6 +2,8 @@ package contentful import ( contentful "github.com/flaconi/contentful-go" + "github.com/flaconi/contentful-go/pkgs/common" + "github.com/flaconi/terraform-provider-contentful/internal/utils" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) @@ -32,7 +34,7 @@ func resourceContentfulSpace() *schema.Resource { } func resourceSpaceCreate(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Client) + client := m.(utils.ProviderData).Client space := &contentful.Space{ Name: d.Get("name").(string), @@ -55,11 +57,11 @@ func resourceSpaceCreate(d *schema.ResourceData, m interface{}) (err error) { } func resourceSpaceRead(d *schema.ResourceData, m interface{}) error { - client := m.(*contentful.Client) + client := m.(utils.ProviderData).Client spaceID := d.Id() _, err := client.Spaces.Get(spaceID) - if _, ok := err.(contentful.NotFoundError); ok { + if _, ok := err.(common.NotFoundError); ok { d.SetId("") return nil } @@ -68,7 +70,7 @@ func resourceSpaceRead(d *schema.ResourceData, m interface{}) error { } func resourceSpaceUpdate(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Client) + client := m.(utils.ProviderData).Client spaceID := d.Id() space, err := client.Spaces.Get(spaceID) @@ -87,7 +89,7 @@ func resourceSpaceUpdate(d *schema.ResourceData, m interface{}) (err error) { } func resourceSpaceDelete(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Client) + client := m.(utils.ProviderData).Client spaceID := d.Id() space, err := client.Spaces.Get(spaceID) @@ -96,7 +98,7 @@ func resourceSpaceDelete(d *schema.ResourceData, m interface{}) (err error) { } err = client.Spaces.Delete(space) - if _, ok := err.(contentful.NotFoundError); ok { + if _, ok := err.(common.NotFoundError); ok { return nil } diff --git a/contentful/resource_contentful_webhook.go b/contentful/resource_contentful_webhook.go index 2573d9a..6d62ab4 100644 --- a/contentful/resource_contentful_webhook.go +++ b/contentful/resource_contentful_webhook.go @@ -2,6 +2,8 @@ package contentful import ( contentful "github.com/flaconi/contentful-go" + "github.com/flaconi/contentful-go/pkgs/common" + "github.com/flaconi/terraform-provider-contentful/internal/utils" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) @@ -57,7 +59,7 @@ func resourceContentfulWebhook() *schema.Resource { } func resourceCreateWebhook(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Client) + client := m.(utils.ProviderData).Client spaceID := d.Get("space_id").(string) webhook := &contentful.Webhook{ @@ -85,7 +87,7 @@ func resourceCreateWebhook(d *schema.ResourceData, m interface{}) (err error) { } func resourceUpdateWebhook(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Client) + client := m.(utils.ProviderData).Client spaceID := d.Get("space_id").(string) webhookID := d.Id() @@ -117,12 +119,12 @@ func resourceUpdateWebhook(d *schema.ResourceData, m interface{}) (err error) { } func resourceReadWebhook(d *schema.ResourceData, m interface{}) error { - client := m.(*contentful.Client) + client := m.(utils.ProviderData).Client spaceID := d.Get("space_id").(string) webhookID := d.Id() webhook, err := client.Webhooks.Get(spaceID, webhookID) - if _, ok := err.(contentful.NotFoundError); ok { + if _, ok := err.(common.NotFoundError); ok { d.SetId("") return nil } @@ -135,7 +137,7 @@ func resourceReadWebhook(d *schema.ResourceData, m interface{}) error { } func resourceDeleteWebhook(d *schema.ResourceData, m interface{}) (err error) { - client := m.(*contentful.Client) + client := m.(utils.ProviderData).Client spaceID := d.Get("space_id").(string) webhookID := d.Id() @@ -145,7 +147,7 @@ func resourceDeleteWebhook(d *schema.ResourceData, m interface{}) (err error) { } err = client.Webhooks.Delete(spaceID, webhook) - if _, ok := err.(contentful.NotFoundError); ok { + if _, ok := err.(common.NotFoundError); ok { return nil } diff --git a/contentful/resource_contentful_webhook_test.go b/contentful/resource_contentful_webhook_test.go index 719caf7..3cac3db 100644 --- a/contentful/resource_contentful_webhook_test.go +++ b/contentful/resource_contentful_webhook_test.go @@ -2,6 +2,8 @@ package contentful import ( "fmt" + "github.com/flaconi/contentful-go/pkgs/common" + "github.com/flaconi/terraform-provider-contentful/internal/acctest" "testing" contentful "github.com/flaconi/contentful-go" @@ -63,7 +65,7 @@ func testAccCheckContentfulWebhookExists(n string, webhook *contentful.Webhook) return fmt.Errorf("no webhook ID is set") } - client := testAccProvider.Meta().(*contentful.Client) + client := acctest.GetClient() contentfulWebhook, err := client.Webhooks.Get(spaceID, rs.Primary.ID) if err != nil { @@ -119,10 +121,10 @@ func testAccContentfulWebhookDestroy(s *terraform.State) error { } // sdk client - client := testAccProvider.Meta().(*contentful.Client) + client := acctest.GetClient() _, err := client.Webhooks.Get(spaceID, rs.Primary.ID) - if _, ok := err.(contentful.NotFoundError); ok { + if _, ok := err.(common.NotFoundError); ok { return nil } diff --git a/examples/resources/contentful_asset/resource.tf b/examples/resources/contentful_asset/resource.tf index f7466aa..a69c476 100644 --- a/examples/resources/contentful_asset/resource.tf +++ b/examples/resources/contentful_asset/resource.tf @@ -1,6 +1,6 @@ resource "contentful_asset" "example_asset" { asset_id = "test_asset" - locale = "en-US" + environment = "master" space_id = "space-id" fields { diff --git a/examples/resources/contentful_entry/resource.tf b/examples/resources/contentful_entry/resource.tf index c1ebf51..943a86a 100644 --- a/examples/resources/contentful_entry/resource.tf +++ b/examples/resources/contentful_entry/resource.tf @@ -2,7 +2,7 @@ resource "contentful_entry" "example_entry" { entry_id = "mytestentry" space_id = "space-id" contenttype_id = "type-id" - locale = "en-US" + environment = "master" field { id = "field1" content = "Hello, World!" diff --git a/go.mod b/go.mod index 1e64821..e8b506a 100644 --- a/go.mod +++ b/go.mod @@ -4,69 +4,76 @@ go 1.21 require ( github.com/elliotchance/pie/v2 v2.8.0 - github.com/flaconi/contentful-go v0.5.3-0.20231219101222-e8e6531b72bb - github.com/hashicorp/terraform-plugin-docs v0.16.0 - github.com/hashicorp/terraform-plugin-framework v1.4.2 + github.com/flaconi/contentful-go v0.5.3-0.20240307133521-ac9bdf1c97f2 + github.com/hashicorp/terraform-plugin-docs v0.18.0 + github.com/hashicorp/terraform-plugin-framework v1.6.1 github.com/hashicorp/terraform-plugin-framework-jsontypes v0.1.0 github.com/hashicorp/terraform-plugin-framework-validators v0.12.0 - github.com/hashicorp/terraform-plugin-mux v0.12.0 - github.com/hashicorp/terraform-plugin-testing v1.6.0 - github.com/stretchr/testify v1.8.4 + github.com/hashicorp/terraform-plugin-mux v0.15.0 + github.com/hashicorp/terraform-plugin-testing v1.7.0 + github.com/stretchr/testify v1.9.0 ) require ( + github.com/Kunde21/markdownfmt/v3 v3.1.0 // indirect github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/semver/v3 v3.2.1 // indirect github.com/Masterminds/sprig/v3 v3.2.3 // indirect - github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 // indirect + github.com/ProtonMail/go-crypto v1.1.0-alpha.1-proton // indirect github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect github.com/armon/go-radix v1.0.0 // indirect github.com/bgentry/speakeasy v0.1.0 // indirect - github.com/cloudflare/circl v1.3.3 // indirect + github.com/cloudflare/circl v1.3.7 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/google/uuid v1.3.1 // indirect - github.com/hashicorp/hc-install v0.6.1 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/hashicorp/cli v1.1.6 // indirect + github.com/hashicorp/hc-install v0.6.3 // indirect github.com/hashicorp/terraform-plugin-log v0.9.0 // indirect github.com/hashicorp/terraform-registry-address v0.2.3 // indirect github.com/hashicorp/terraform-svchost v0.1.1 // indirect github.com/huandu/xstrings v1.4.0 // indirect github.com/imdario/mergo v0.3.16 // indirect - github.com/mitchellh/cli v1.1.5 // indirect + github.com/mattn/go-runewidth v0.0.15 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/posener/complete v1.2.3 // indirect + github.com/rivo/uniseg v0.4.7 // indirect github.com/russross/blackfriday v1.6.0 // indirect github.com/shopspring/decimal v1.3.1 // indirect - github.com/spf13/cast v1.5.1 // indirect + github.com/spf13/cast v1.6.0 // indirect github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect - golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20230913181813-007df8e322eb // indirect + github.com/yuin/goldmark v1.7.0 // indirect + github.com/yuin/goldmark-meta v1.1.0 // indirect + golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 // indirect + golang.org/x/tools v0.19.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240304212257-790db918fca8 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) require ( github.com/agext/levenshtein v1.2.3 // indirect - github.com/fatih/color v1.15.0 // indirect - github.com/golang/protobuf v1.5.3 // indirect + github.com/fatih/color v1.16.0 // indirect + github.com/golang/protobuf v1.5.4 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-checkpoint v0.5.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 // indirect - github.com/hashicorp/go-hclog v1.5.0 // indirect + github.com/hashicorp/go-hclog v1.6.2 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect - github.com/hashicorp/go-plugin v1.5.2 // indirect + github.com/hashicorp/go-plugin v1.6.0 // indirect github.com/hashicorp/go-uuid v1.0.3 // indirect github.com/hashicorp/go-version v1.6.0 // indirect - github.com/hashicorp/hcl/v2 v2.19.1 // indirect + github.com/hashicorp/hcl/v2 v2.20.0 // indirect github.com/hashicorp/logutils v1.0.0 // indirect - github.com/hashicorp/terraform-exec v0.19.0 // indirect - github.com/hashicorp/terraform-json v0.18.0 // indirect - github.com/hashicorp/terraform-plugin-go v0.19.1 - github.com/hashicorp/terraform-plugin-sdk/v2 v2.30.0 + github.com/hashicorp/terraform-exec v0.20.0 // indirect + github.com/hashicorp/terraform-json v0.21.0 // indirect + github.com/hashicorp/terraform-plugin-go v0.22.0 + github.com/hashicorp/terraform-plugin-sdk/v2 v2.33.0 github.com/hashicorp/yamux v0.1.1 // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.19 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/go-testing-interface v1.14.1 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect @@ -74,16 +81,14 @@ require ( github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/oklog/run v1.1.0 // indirect github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect - github.com/zclconf/go-cty v1.14.1 // indirect - golang.org/x/crypto v0.16.0 // indirect - golang.org/x/mod v0.13.0 // indirect - golang.org/x/net v0.17.0 // indirect - golang.org/x/sys v0.15.0 // indirect + github.com/zclconf/go-cty v1.14.3 // indirect + golang.org/x/crypto v0.21.0 // indirect + golang.org/x/mod v0.16.0 // indirect + golang.org/x/net v0.22.0 // indirect + golang.org/x/sys v0.18.0 // indirect golang.org/x/text v0.14.0 // indirect google.golang.org/appengine v1.6.8 // indirect - google.golang.org/grpc v1.59.0 // indirect - google.golang.org/protobuf v1.31.0 // indirect + google.golang.org/grpc v1.62.1 // indirect + google.golang.org/protobuf v1.33.0 // indirect moul.io/http2curl v1.0.1-0.20190925090545-5cd742060b0e // indirect ) - -//replace github.com/flaconi/contentful-go => /Users/alexander.miehe/projects/flaconi/go/contentful-go diff --git a/go.sum b/go.sum index 1498e2d..444dee6 100644 --- a/go.sum +++ b/go.sum @@ -1,35 +1,31 @@ dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +github.com/Kunde21/markdownfmt/v3 v3.1.0 h1:KiZu9LKs+wFFBQKhrZJrFZwtLnCCWJahL+S+E/3VnM0= +github.com/Kunde21/markdownfmt/v3 v3.1.0/go.mod h1:tPXN1RTyOzJwhfHoon9wUr4HGYmWgVxSQN6VBJDkrVc= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= -github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= -github.com/Masterminds/sprig/v3 v3.2.1/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk= github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA= github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= -github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 h1:kkhsdkhsCvIsutKu5zLMgWtgh9YxGCNAw8Ad8hjwfYg= -github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= -github.com/acomagu/bufpipe v1.0.4 h1:e3H4WUzM3npvo5uv95QuJM3cQspFNtFBzvJ2oNjKIDQ= -github.com/acomagu/bufpipe v1.0.4/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4= +github.com/ProtonMail/go-crypto v1.1.0-alpha.1-proton h1:R+MMcIpg1nTjsYabIeFNR18j2V+3WT25xClrsrR0O6A= +github.com/ProtonMail/go-crypto v1.1.0-alpha.1-proton/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec= github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY= github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4= -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/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA= github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8= -github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= -github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs= -github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= +github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= +github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -39,20 +35,19 @@ github.com/elliotchance/pie/v2 v2.8.0 h1://QS43W8sEha8XV/fjngO5iMudN3XARJV5cpBay github.com/elliotchance/pie/v2 v2.8.0/go.mod h1:18t0dgGFH006g4eVdDtWfgFZPQEgl10IoEO8YWEq3Og= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= -github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= -github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= -github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= -github.com/flaconi/contentful-go v0.5.3-0.20231219101222-e8e6531b72bb h1:dvDYCZj8Yu0ShiwsBLaiG3SL2iwIjyWYS77L9I8//jc= -github.com/flaconi/contentful-go v0.5.3-0.20231219101222-e8e6531b72bb/go.mod h1:L5DNUF3KQXA5z9iQGqV0KcqN++U4bBDPjBSMG/94GHQ= -github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= -github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= +github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= +github.com/flaconi/contentful-go v0.5.3-0.20240307133521-ac9bdf1c97f2 h1:h2Q7lCAU/DP3yFz7GRRKSKKoHyepnyEwll1pg8x3BS8= +github.com/flaconi/contentful-go v0.5.3-0.20240307133521-ac9bdf1c97f2/go.mod h1:j6xpYF+19owGCT9j6Wx5XaM8Gub9s5UcXUMw4B4teZY= +github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU= github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow= -github.com/go-git/go-git/v5 v5.9.0 h1:cD9SFA7sHVRdJ7AYck1ZaAa/yeuBvGPxwXDL8cxrObY= -github.com/go-git/go-git/v5 v5.9.0/go.mod h1:RKIqga24sWdMGZF+1Ekv9kylsDz6LzdTSI2s/OsZWE0= +github.com/go-git/go-git/v5 v5.11.0 h1:XIZc1p+8YzypNr34itUfSvYJcv+eYdTnTvOZ2vD3cA4= +github.com/go-git/go-git/v5 v5.11.0/go.mod h1:6GFcX2P3NM7FPBfpePbpLd21XxsgdAt+lKqXmCUiUCY= 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/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= @@ -60,16 +55,17 @@ github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4er github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= -github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/hashicorp/cli v1.1.6 h1:CMOV+/LJfL1tXCOKrgAX0uRKnzjj/mpmqNXloRSy2K8= +github.com/hashicorp/cli v1.1.6/go.mod h1:MPon5QYlgjjo0BSoAiN0ESeT5fRzDjVRp+uioJ0piz4= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -80,54 +76,52 @@ github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9n github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 h1:1/D3zfFHttUKaCaGKZ/dR2roBXv0vKbSCnssIldfQdI= github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320/go.mod h1:EiZBMaudVLy8fmjf9Npq1dq9RalhveqZG5w/yz3mHWs= -github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c= -github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/go-hclog v1.6.2 h1:NOtoftovWkDheyUM/8JW3QMiXyxJK3uHRK7wV04nD2I= +github.com/hashicorp/go-hclog v1.6.2/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/go-plugin v1.5.2 h1:aWv8eimFqWlsEiMrYZdPYl+FdHaBJSN4AWwGWfT1G2Y= -github.com/hashicorp/go-plugin v1.5.2/go.mod h1:w1sAEES3g3PuV/RzUrgow20W2uErMly84hhD3um1WL4= +github.com/hashicorp/go-plugin v1.6.0 h1:wgd4KxHJTVGGqWBq4QPB1i5BZNEx9BR8+OFmHDmTk8A= +github.com/hashicorp/go-plugin v1.6.0/go.mod h1:lBS5MtSSBZk0SHc66KACcjjlU6WzEVP/8pwz68aMkCI= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/hc-install v0.6.1 h1:IGxShH7AVhPaSuSJpKtVi/EFORNjO+OYVJJrAtGG2mY= -github.com/hashicorp/hc-install v0.6.1/go.mod h1:0fW3jpg+wraYSnFDJ6Rlie3RvLf1bIqVIkzoon4KoVE= -github.com/hashicorp/hcl/v2 v2.19.1 h1://i05Jqznmb2EXqa39Nsvyan2o5XyMowW5fnCKW5RPI= -github.com/hashicorp/hcl/v2 v2.19.1/go.mod h1:ThLC89FV4p9MPW804KVbe/cEXoQ8NZEh+JtMeeGErHE= +github.com/hashicorp/hc-install v0.6.3 h1:yE/r1yJvWbtrJ0STwScgEnCanb0U9v7zp0Gbkmcoxqs= +github.com/hashicorp/hc-install v0.6.3/go.mod h1:KamGdbodYzlufbWh4r9NRo8y6GLHWZP2GBtdnms1Ln0= +github.com/hashicorp/hcl/v2 v2.20.0 h1:l++cRs/5jQOiKVvqXZm/P1ZEfVXJmvLS9WSVxkaeTb4= +github.com/hashicorp/hcl/v2 v2.20.0/go.mod h1:WmcD/Ym72MDOOx5F62Ly+leloeu6H7m0pG7VBiU6pQk= 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/terraform-exec v0.19.0 h1:FpqZ6n50Tk95mItTSS9BjeOVUb4eg81SpgVtZNNtFSM= -github.com/hashicorp/terraform-exec v0.19.0/go.mod h1:tbxUpe3JKruE9Cuf65mycSIT8KiNPZ0FkuTE3H4urQg= -github.com/hashicorp/terraform-json v0.18.0 h1:pCjgJEqqDESv4y0Tzdqfxr/edOIGkjs8keY42xfNBwU= -github.com/hashicorp/terraform-json v0.18.0/go.mod h1:qdeBs11ovMzo5puhrRibdD6d2Dq6TyE/28JiU4tIQxk= -github.com/hashicorp/terraform-plugin-docs v0.16.0 h1:UmxFr3AScl6Wged84jndJIfFccGyBZn52KtMNsS12dI= -github.com/hashicorp/terraform-plugin-docs v0.16.0/go.mod h1:M3ZrlKBJAbPMtNOPwHicGi1c+hZUh7/g0ifT/z7TVfA= -github.com/hashicorp/terraform-plugin-framework v1.4.2 h1:P7a7VP1GZbjc4rv921Xy5OckzhoiO3ig6SGxwelD2sI= -github.com/hashicorp/terraform-plugin-framework v1.4.2/go.mod h1:GWl3InPFZi2wVQmdVnINPKys09s9mLmTZr95/ngLnbY= +github.com/hashicorp/terraform-exec v0.20.0 h1:DIZnPsqzPGuUnq6cH8jWcPunBfY+C+M8JyYF3vpnuEo= +github.com/hashicorp/terraform-exec v0.20.0/go.mod h1:ckKGkJWbsNqFKV1itgMnE0hY9IYf1HoiekpuN0eWoDw= +github.com/hashicorp/terraform-json v0.21.0 h1:9NQxbLNqPbEMze+S6+YluEdXgJmhQykRyRNd+zTI05U= +github.com/hashicorp/terraform-json v0.21.0/go.mod h1:qdeBs11ovMzo5puhrRibdD6d2Dq6TyE/28JiU4tIQxk= +github.com/hashicorp/terraform-plugin-docs v0.18.0 h1:2bINhzXc+yDeAcafurshCrIjtdu1XHn9zZ3ISuEhgpk= +github.com/hashicorp/terraform-plugin-docs v0.18.0/go.mod h1:iIUfaJpdUmpi+rI42Kgq+63jAjI8aZVTyxp3Bvk9Hg8= +github.com/hashicorp/terraform-plugin-framework v1.6.1 h1:hw2XrmUu8d8jVL52ekxim2IqDc+2Kpekn21xZANARLU= +github.com/hashicorp/terraform-plugin-framework v1.6.1/go.mod h1:aJI+n/hBPhz1J+77GdgNfk5svW12y7fmtxe/5L5IuwI= github.com/hashicorp/terraform-plugin-framework-jsontypes v0.1.0 h1:b8vZYB/SkXJT4YPbT3trzE6oJ7dPyMy68+9dEDKsJjE= github.com/hashicorp/terraform-plugin-framework-jsontypes v0.1.0/go.mod h1:tP9BC3icoXBz72evMS5UTFvi98CiKhPdXF6yLs1wS8A= github.com/hashicorp/terraform-plugin-framework-validators v0.12.0 h1:HOjBuMbOEzl7snOdOoUfE2Jgeto6JOjLVQ39Ls2nksc= github.com/hashicorp/terraform-plugin-framework-validators v0.12.0/go.mod h1:jfHGE/gzjxYz6XoUwi/aYiiKrJDeutQNUtGQXkaHklg= -github.com/hashicorp/terraform-plugin-go v0.19.1 h1:lf/jTGTeELcz5IIbn/94mJdmnTjRYm6S6ct/JqCSr50= -github.com/hashicorp/terraform-plugin-go v0.19.1/go.mod h1:5NMIS+DXkfacX6o5HCpswda5yjkSYfKzn1Nfl9l+qRs= +github.com/hashicorp/terraform-plugin-go v0.22.0 h1:1OS1Jk5mO0f5hrziWJGXXIxBrMe2j/B8E+DVGw43Xmc= +github.com/hashicorp/terraform-plugin-go v0.22.0/go.mod h1:mPULV91VKss7sik6KFEcEu7HuTogMLLO/EvWCuFkRVE= github.com/hashicorp/terraform-plugin-log v0.9.0 h1:i7hOA+vdAItN1/7UrfBqBwvYPQ9TFvymaRGZED3FCV0= github.com/hashicorp/terraform-plugin-log v0.9.0/go.mod h1:rKL8egZQ/eXSyDqzLUuwUYLVdlYeamldAHSxjUFADow= -github.com/hashicorp/terraform-plugin-mux v0.12.0 h1:TJlmeslQ11WlQtIFAfth0vXx+gSNgvMEng2Rn9z3WZY= -github.com/hashicorp/terraform-plugin-mux v0.12.0/go.mod h1:8MR0AgmV+Q03DIjyrAKxXyYlq2EUnYBQP8gxAAA0zeM= -github.com/hashicorp/terraform-plugin-sdk/v2 v2.30.0 h1:X7vB6vn5tON2b49ILa4W7mFAsndeqJ7bZFOGbVO+0Cc= -github.com/hashicorp/terraform-plugin-sdk/v2 v2.30.0/go.mod h1:ydFcxbdj6klCqYEPkPvdvFKiNGKZLUs+896ODUXCyao= -github.com/hashicorp/terraform-plugin-testing v1.6.0 h1:Wsnfh+7XSVRfwcr2jZYHsnLOnZl7UeaOBvsx6dl/608= -github.com/hashicorp/terraform-plugin-testing v1.6.0/go.mod h1:cJGG0/8j9XhHaJZRC+0sXFI4uzqQZ9Az4vh6C4GJpFE= +github.com/hashicorp/terraform-plugin-mux v0.15.0 h1:+/+lDx0WUsIOpkAmdwBIoFU8UP9o2eZASoOnLsWbKME= +github.com/hashicorp/terraform-plugin-mux v0.15.0/go.mod h1:9ezplb1Dyq394zQ+ldB0nvy/qbNAz3mMoHHseMTMaKo= +github.com/hashicorp/terraform-plugin-sdk/v2 v2.33.0 h1:qHprzXy/As0rxedphECBEQAh3R4yp6pKksKHcqZx5G8= +github.com/hashicorp/terraform-plugin-sdk/v2 v2.33.0/go.mod h1:H+8tjs9TjV2w57QFVSMBQacf8k/E1XwLXGCARgViC6A= +github.com/hashicorp/terraform-plugin-testing v1.7.0 h1:I6aeCyZ30z4NiI3tzyDoO6fS7YxP5xSL1ceOon3gTe8= +github.com/hashicorp/terraform-plugin-testing v1.7.0/go.mod h1:sbAreCleJNOCz+y5vVHV8EJkIWZKi/t4ndKiUjM9vao= github.com/hashicorp/terraform-registry-address v0.2.3 h1:2TAiKJ1A3MAkZlH1YI/aTVcLZRu7JseiXNRHbOAyoTI= github.com/hashicorp/terraform-registry-address v0.2.3/go.mod h1:lFHA76T8jfQteVfT7caREqguFrW3c4MFSPhZB7HHgUM= github.com/hashicorp/terraform-svchost v0.1.1 h1:EZZimZ1GxdqFRinZ1tpJwVxxt49xc/S52uzrw4x0jKQ= github.com/hashicorp/terraform-svchost v0.1.1/go.mod h1:mNsjQfZyf/Jhz35v6/0LWcv26+X7JPS+buii2c9/ctc= github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE= github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= -github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= -github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU= github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= @@ -149,19 +143,17 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= 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/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= -github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mitchellh/cli v1.1.5 h1:OxRIeJXpAMztws/XHlN2vu6imG5Dpq+j61AzAX5fLng= -github.com/mitchellh/cli v1.1.5/go.mod h1:v8+iFts2sPIKUV1ltktPXMCC8fumSKFItNcD2cLtRR4= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= +github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= @@ -180,11 +172,13 @@ github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI= 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.3 h1:NP0eAhjcjImqslEwo/1hq7gpajME0fTLTezBKDqfXqo= github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= -github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= -github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= +github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww= github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY= github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= @@ -192,19 +186,18 @@ github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNX github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= -github.com/skeema/knownhosts v1.2.0 h1:h9r9cf0+u7wSE+M183ZtMGgOJKiL96brpaz5ekfJCpM= -github.com/skeema/knownhosts v1.2.0/go.mod h1:g4fPeYpque7P0xefxtGzV81ihjC8sX2IqpAoNkjxbMo= +github.com/skeema/knownhosts v1.2.1 h1:SHWdIUa82uGZz+F+47k8SY4QhhI291cXCpopT1lK2AQ= +github.com/skeema/knownhosts v1.2.1/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA= -github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48= +github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= +github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI= github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= @@ -215,38 +208,35 @@ github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/zclconf/go-cty v1.14.1 h1:t9fyA35fwjjUMcmL5hLER+e/rEPqrbCK1/OSE4SI9KA= -github.com/zclconf/go-cty v1.14.1/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= +github.com/yuin/goldmark v1.7.0 h1:EfOIvIMZIzHdB/R/zVrikYLPPwJlfMcNczJFMs1m6sA= +github.com/yuin/goldmark v1.7.0/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= +github.com/yuin/goldmark-meta v1.1.0 h1:pWw+JLHGZe8Rk0EGsMVssiNb/AaPMHfSRszZeUeiOUc= +github.com/yuin/goldmark-meta v1.1.0/go.mod h1:U4spWENafuA7Zyg+Lj5RqK/MF+ovMYtBvXi1lBb2VP0= +github.com/zclconf/go-cty v1.14.3 h1:1JXy1XroaGrzZuG6X9dt7HL6s9AwbY+l4UNL8o5B6ho= +github.com/zclconf/go-cty v1.14.3/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= -golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= -golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= -golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY= -golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= -golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= -golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= +golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= +golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 h1:LfspQV/FYTatPTr/3HzIcmiUFH7PGP+OQ6mgDYo3yuQ= +golang.org/x/exp v0.0.0-20240222234643-814bf88cf225/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= -golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.16.0 h1:QX4fJ0Rr5cPQCF7O9lh9Se4pmwfwskqZfq5moyldzic= +golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= +golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -258,47 +248,40 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= -golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= -golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= -golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= +golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= +golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= -golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= +golang.org/x/tools v0.19.0 h1:tfGCXNR1OsFG+sVdLAitlpjAvD/I6dHDKnYrpEZUHkw= +golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230913181813-007df8e322eb h1:Isk1sSH7bovx8Rti2wZK0UZF6oraBDK74uoyLEEVFN0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230913181813-007df8e322eb/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= -google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk= -google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240304212257-790db918fca8 h1:IR+hp6ypxjH24bkMfEJ0yHR21+gwPWdV+/IBrPQyn3k= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240304212257-790db918fca8/go.mod h1:UCOku4NytXMJuLQE5VuqA5lX3PcHCBo8pxNyvkf4xBs= +google.golang.org/grpc v1.62.1 h1:B4n+nfKzOICUXMgyrNd19h/I9oH0L1pizfk1d4zSgTk= +google.golang.org/grpc v1.62.1/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -306,7 +289,8 @@ gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= moul.io/http2curl v1.0.1-0.20190925090545-5cd742060b0e h1:C7q+e9M5nggAvWfVg9Nl66kebKeuJlP3FD58V4RR5wo= diff --git a/internal/acctest/client.go b/internal/acctest/client.go index 5cbc7ec..2c05568 100644 --- a/internal/acctest/client.go +++ b/internal/acctest/client.go @@ -3,7 +3,8 @@ package acctest import ( "github.com/flaconi/contentful-go" client2 "github.com/flaconi/contentful-go/pkgs/client" - "github.com/flaconi/contentful-go/service/common" + "github.com/flaconi/contentful-go/pkgs/util" + "github.com/flaconi/contentful-go/service/cma" "os" ) @@ -16,11 +17,10 @@ func GetClient() *contentful.Client { return cma } -func GetCMA() common.SpaceIdClientBuilder { +func GetCMA() cma.SpaceIdClientBuilder { client, err := contentful.NewCMAV2(client2.ClientConfig{ - URL: "https://api.contentful.com", Debug: false, - UserAgent: "terraform-provider-contentful-test", + UserAgent: util.ToPointer("terraform-provider-contentful-test"), Token: os.Getenv("CONTENTFUL_MANAGEMENT_TOKEN"), }) diff --git a/internal/custommodifier/listdefault.go b/internal/custommodifier/listdefault.go new file mode 100644 index 0000000..f1d73bc --- /dev/null +++ b/internal/custommodifier/listdefault.go @@ -0,0 +1,47 @@ +package custommodifier + +import ( + "context" + "fmt" + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +// From https://developer.hashicorp.com/terraform/plugin/framework/resources/plan-modification#creating-attribute-plan-modifiers + +var _ planmodifier.List = listDefaultModifier{} +var _ planmodifier.Describer = listDefaultModifier{} + +type listDefaultModifier struct { + Default []attr.Value +} + +func (l listDefaultModifier) Description(_ context.Context) string { + return fmt.Sprintf("If value is not configured, defaults to %s", l.Default) +} + +func (l listDefaultModifier) MarkdownDescription(ctx context.Context) string { + return l.Description(ctx) +} + +func (l listDefaultModifier) PlanModifyList(ctx context.Context, _ planmodifier.ListRequest, resp *planmodifier.ListResponse) { + // If the value is unknown or known, do not set default value. + if resp.PlanValue.IsNull() || resp.PlanValue.IsUnknown() { + planValue, diags := types.ListValue(resp.PlanValue.ElementType(ctx), l.Default) + + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + resp.PlanValue = planValue + } +} + +func ListDefault(defaultValue []attr.Value) planmodifier.List { + return listDefaultModifier{ + Default: defaultValue, + } +} diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 8823fa1..28f026f 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -4,6 +4,7 @@ import ( "context" "github.com/flaconi/contentful-go" client2 "github.com/flaconi/contentful-go/pkgs/client" + "github.com/flaconi/contentful-go/pkgs/util" "github.com/flaconi/terraform-provider-contentful/internal/resources/api_key" "github.com/flaconi/terraform-provider-contentful/internal/resources/app_definition" "github.com/flaconi/terraform-provider-contentful/internal/resources/app_installation" @@ -98,9 +99,8 @@ func (c contentfulProvider) Configure(ctx context.Context, request provider.Conf cma.Debug = debug client, err := contentful.NewCMAV2(client2.ClientConfig{ - URL: "https://api.contentful.com", Debug: debug, - UserAgent: "terraform-provider-contentful", + UserAgent: util.ToPointer("terraform-provider-contentful"), Token: cmaToken, }) diff --git a/internal/resources/api_key/model.go b/internal/resources/api_key/model.go index d3d35fa..16d76da 100644 --- a/internal/resources/api_key/model.go +++ b/internal/resources/api_key/model.go @@ -41,7 +41,7 @@ func (a *ApiKey) Draft() *model.APIKey { draft := &model.APIKey{} if !a.ID.IsUnknown() || !a.ID.IsNull() { - draft.Sys = &model.SpaceSys{BaseSys: model.BaseSys{ID: a.ID.ValueString(), Version: int(a.Version.ValueInt64())}} + draft.Sys = &model.SpaceSys{CreatedSys: model.CreatedSys{BaseSys: model.BaseSys{ID: a.ID.ValueString(), Version: int(a.Version.ValueInt64())}}} } diff --git a/internal/resources/api_key/resource.go b/internal/resources/api_key/resource.go index e608fca..758c44a 100644 --- a/internal/resources/api_key/resource.go +++ b/internal/resources/api_key/resource.go @@ -4,8 +4,10 @@ import ( "context" "fmt" "github.com/flaconi/contentful-go/pkgs/model" - "github.com/flaconi/contentful-go/service/common" + "github.com/flaconi/contentful-go/service/cma" + "github.com/flaconi/terraform-provider-contentful/internal/custommodifier" "github.com/flaconi/terraform-provider-contentful/internal/utils" + "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/resource/schema" @@ -29,7 +31,7 @@ func NewApiKeyResource() resource.Resource { // apiKeyResource is the resource implementation. type apiKeyResource struct { - client common.SpaceIdClientBuilder + client cma.SpaceIdClientBuilder } func (e *apiKeyResource) Metadata(_ context.Context, request resource.MetadataRequest, response *resource.MetadataResponse) { @@ -81,8 +83,12 @@ func (e *apiKeyResource) Schema(_ context.Context, _ resource.SchemaRequest, res }, "environments": schema.ListAttribute{ Optional: true, + Computed: true, Description: "List of needed environments if not added then master is used", ElementType: types.StringType, + PlanModifiers: []planmodifier.List{ + custommodifier.ListDefault([]attr.Value{types.StringValue("master")}), + }, }, }, } diff --git a/internal/resources/api_key/resource_test.go b/internal/resources/api_key/resource_test.go index e389939..71ba8e9 100644 --- a/internal/resources/api_key/resource_test.go +++ b/internal/resources/api_key/resource_test.go @@ -45,6 +45,7 @@ func TestApiKeyResource_Create(t *testing.T) { assert.EqualValues(t, name, apiKey.Name) assert.EqualValues(t, description, apiKey.Description) assert.Regexp(t, regexp.MustCompile(`^[a-zA-Z0-9-_.]{1,64}$`), apiKey.Sys.ID) + assert.EqualValues(t, "master", apiKey.Environments[0].Sys.ID) }), ), }, @@ -67,6 +68,37 @@ func TestApiKeyResource_Create(t *testing.T) { }) } +func TestApiKeyResource_CreateWithEnvironmentSet(t *testing.T) { + name := fmt.Sprintf("apikey-name-%s", hashicor_acctest.RandString(3)) + description := fmt.Sprintf("apikey-description-%s", hashicor_acctest.RandString(3)) + resourceName := "contentful_apikey.myapikey" + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.TestAccPreCheck(t) }, + CheckDestroy: testAccCheckContentfulApiKeyDestroy, + ProtoV6ProviderFactories: map[string]func() (tfprotov6.ProviderServer, error){ + "contentful": providerserver.NewProtocol6WithError(provider.New("test", true)), + }, + Steps: []resource.TestStep{ + { + Config: testApiKeyWithEnvironment(os.Getenv("CONTENTFUL_SPACE_ID"), name, description), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "name", name), + resource.TestCheckResourceAttr(resourceName, "description", description), + resource.TestMatchResourceAttr(resourceName, "id", regexp.MustCompile(`^[a-zA-Z0-9-_.]{1,64}$`)), + resource.TestMatchResourceAttr(resourceName, "preview_id", regexp.MustCompile(`^[a-zA-Z0-9-_.]{1,64}$`)), + testAccCheckContentfulApiKeyExists(t, resourceName, func(t *testing.T, apiKey *model.APIKey) { + assert.NotEmpty(t, apiKey.AccessToken) + assert.EqualValues(t, name, apiKey.Name) + assert.EqualValues(t, description, apiKey.Description) + assert.Regexp(t, regexp.MustCompile(`^[a-zA-Z0-9-_.]{1,64}$`), apiKey.Sys.ID) + assert.EqualValues(t, "notexisting", apiKey.Environments[0].Sys.ID) + }), + ), + }, + }, + }) +} + func testAccCheckContentfulApiKeyExists(t *testing.T, resourceName string, assertFunc assertFunc) resource.TestCheckFunc { return func(s *terraform.State) error { definition, err := getApiKeyFromState(s, resourceName) @@ -122,6 +154,15 @@ func testApiKey(spaceId string, name string, description string) string { }) } +func testApiKeyWithEnvironment(spaceId string, name string, description string) string { + return utils.HCLTemplateFromPath("test_resources/create.tf", map[string]any{ + "spaceId": spaceId, + "name": name, + "description": description, + "environments": []string{"notexisting"}, + }) +} + func testApiKeyUpdate(spaceId string, name string, description string) string { return utils.HCLTemplateFromPath("test_resources/update.tf", map[string]any{ "spaceId": spaceId, diff --git a/internal/resources/api_key/test_resources/create.tf b/internal/resources/api_key/test_resources/create.tf index 9cd4761..758395e 100644 --- a/internal/resources/api_key/test_resources/create.tf +++ b/internal/resources/api_key/test_resources/create.tf @@ -3,4 +3,11 @@ resource "contentful_apikey" "myapikey" { name = "{{ .name }}" description = "{{ .description }}" + + {{if .environments}} + + environments = [ {{range .environments}}"{{.}}",{{end}}] + + {{end}} + } \ No newline at end of file diff --git a/internal/resources/app_definition/model.go b/internal/resources/app_definition/model.go index 7a0760a..eeb319a 100644 --- a/internal/resources/app_definition/model.go +++ b/internal/resources/app_definition/model.go @@ -2,7 +2,7 @@ package app_definition import ( "github.com/elliotchance/pie/v2" - "github.com/flaconi/contentful-go" + "github.com/flaconi/contentful-go/pkgs/model" "github.com/flaconi/terraform-provider-contentful/internal/utils" "github.com/hashicorp/terraform-plugin-framework/types" ) @@ -17,12 +17,12 @@ type AppDefinition struct { Locations []Location `tfsdk:"locations"` } -func (a AppDefinition) Draft() *contentful.AppDefinition { +func (a AppDefinition) Draft() *model.AppDefinition { - app := &contentful.AppDefinition{} + app := &model.AppDefinition{} if !a.ID.IsUnknown() || !a.ID.IsNull() { - app.Sys = &contentful.Sys{ID: a.ID.ValueString()} + app.Sys = &model.CreatedSys{BaseSys: model.BaseSys{ID: a.ID.ValueString()}} } if !a.Src.IsNull() && !a.Src.IsUnknown() { @@ -31,12 +31,12 @@ func (a AppDefinition) Draft() *contentful.AppDefinition { app.Name = a.Name.ValueString() - app.Locations = pie.Map(a.Locations, func(t Location) contentful.Locations { + app.Locations = pie.Map(a.Locations, func(t Location) model.Locations { return t.Draft() }) if a.UseBundle.ValueBool() && !a.BundleId.IsNull() && !a.BundleId.IsUnknown() { - app.Bundle = &contentful.Bundle{Sys: &contentful.Sys{ + app.Bundle = &model.Bundle{Sys: &model.BaseSys{ ID: a.BundleId.ValueString(), Type: "Link", LinkType: "AppBundle", @@ -46,7 +46,7 @@ func (a AppDefinition) Draft() *contentful.AppDefinition { return app } -func (a *AppDefinition) Equal(n *contentful.AppDefinition) bool { +func (a *AppDefinition) Equal(n *model.AppDefinition) bool { if a.Name.ValueString() != n.Name { return false @@ -61,7 +61,7 @@ func (a *AppDefinition) Equal(n *contentful.AppDefinition) bool { } for _, location := range a.Locations { - idx := pie.FindFirstUsing(n.Locations, func(f contentful.Locations) bool { + idx := pie.FindFirstUsing(n.Locations, func(f model.Locations) bool { return f.Location == location.Location.ValueString() }) @@ -73,7 +73,7 @@ func (a *AppDefinition) Equal(n *contentful.AppDefinition) bool { return true } -func (a *AppDefinition) Import(n *contentful.AppDefinition) { +func (a *AppDefinition) Import(n *model.AppDefinition) { a.ID = types.StringValue(n.Sys.ID) a.UseBundle = types.BoolValue(false) a.BundleId = types.StringNull() @@ -104,7 +104,7 @@ type Location struct { NavigationItem *NavigationItem `tfsdk:"navigation_item"` } -func (l *Location) Import(n contentful.Locations) { +func (l *Location) Import(n model.Locations) { l.Location = types.StringValue(n.Location) if n.NavigationItem != nil { @@ -112,26 +112,26 @@ func (l *Location) Import(n contentful.Locations) { l.NavigationItem.Import(n.NavigationItem) } - l.FieldTypes = pie.Map(n.FieldTypes, func(t contentful.FieldType) FieldType { + l.FieldTypes = pie.Map(n.FieldTypes, func(t model.FieldType) FieldType { field := &FieldType{} field.Import(t) return *field }) } -func (l *Location) Draft() contentful.Locations { - location := contentful.Locations{ +func (l *Location) Draft() model.Locations { + location := model.Locations{ Location: l.Location.ValueString(), } if l.NavigationItem != nil { - location.NavigationItem = &contentful.NavigationItem{ + location.NavigationItem = &model.NavigationItem{ Name: l.NavigationItem.Name.ValueString(), Path: l.NavigationItem.Path.String(), } } - location.FieldTypes = pie.Map(l.FieldTypes, func(t FieldType) contentful.FieldType { + location.FieldTypes = pie.Map(l.FieldTypes, func(t FieldType) model.FieldType { return t.Draft() }) @@ -144,8 +144,8 @@ type FieldType struct { Items *Items `tfsdk:"items"` } -func (f *FieldType) Draft() contentful.FieldType { - fieldType := contentful.FieldType{ +func (f *FieldType) Draft() model.FieldType { + fieldType := model.FieldType{ Type: f.Type.ValueString(), LinkType: f.LinkType.ValueStringPointer(), } @@ -157,7 +157,7 @@ func (f *FieldType) Draft() contentful.FieldType { return fieldType } -func (f *FieldType) Import(n contentful.FieldType) { +func (f *FieldType) Import(n model.FieldType) { f.Type = types.StringValue(n.Type) f.LinkType = types.StringPointerValue(n.LinkType) @@ -174,8 +174,8 @@ type Items struct { LinkType types.String `tfsdk:"link_type"` } -func (i *Items) Draft() *contentful.Items { - return &contentful.Items{ +func (i *Items) Draft() *model.Items { + return &model.Items{ Type: i.Type.ValueString(), LinkType: i.LinkType.ValueStringPointer(), } @@ -186,7 +186,7 @@ type NavigationItem struct { Path types.String `tfsdk:"path"` } -func (l *NavigationItem) Import(n *contentful.NavigationItem) { +func (l *NavigationItem) Import(n *model.NavigationItem) { l.Name = types.StringValue(n.Name) l.Path = types.StringValue(n.Path) } diff --git a/internal/resources/app_definition/resource.go b/internal/resources/app_definition/resource.go index daf8464..acf0449 100644 --- a/internal/resources/app_definition/resource.go +++ b/internal/resources/app_definition/resource.go @@ -4,6 +4,8 @@ import ( "context" _ "embed" "github.com/flaconi/contentful-go" + "github.com/flaconi/contentful-go/pkgs/model" + "github.com/flaconi/contentful-go/service/cma" "github.com/flaconi/terraform-provider-contentful/internal/custommodifier" "github.com/flaconi/terraform-provider-contentful/internal/customvalidator" "github.com/flaconi/terraform-provider-contentful/internal/utils" @@ -36,8 +38,9 @@ func NewAppDefinitionResource() resource.Resource { // appDefinitionResource is the resource implementation. type appDefinitionResource struct { - client *contentful.Client - organizationId string + client cma.OrganizationIdClient + clientAppUpload *contentful.Client + organizationId string } func (e *appDefinitionResource) Metadata(_ context.Context, request resource.MetadataRequest, response *resource.MetadataResponse) { @@ -157,8 +160,9 @@ func (e *appDefinitionResource) Configure(_ context.Context, request resource.Co } data := request.ProviderData.(utils.ProviderData) - e.client = data.Client + e.client = data.CMAClient.WithOrganizationId(data.OrganizationId) e.organizationId = data.OrganizationId + e.clientAppUpload = data.Client } @@ -169,13 +173,13 @@ func (e *appDefinitionResource) Create(ctx context.Context, request resource.Cre return } - if e.setDefaultBundle(&plan, response.Diagnostics) { + if e.setDefaultBundle(ctx, &plan, response.Diagnostics) { return } draft := plan.Draft() - if err := e.client.AppDefinitions.Upsert(e.organizationId, draft); err != nil { + if err := e.client.AppDefinitions().Upsert(ctx, draft); err != nil { response.Diagnostics.AddError("Error creating app_definition definition", err.Error()) return } @@ -189,21 +193,21 @@ func (e *appDefinitionResource) Create(ctx context.Context, request resource.Cre } } -func (e *appDefinitionResource) setDefaultBundle(plan *AppDefinition, diagnostics diag.Diagnostics) bool { +func (e *appDefinitionResource) setDefaultBundle(ctx context.Context, plan *AppDefinition, diagnostics diag.Diagnostics) bool { if plan.UseBundle.ValueBool() && (plan.BundleId.IsNull() || plan.BundleId.IsUnknown()) { draft := plan.Draft() locations := draft.Locations - draft.Locations = []contentful.Locations{} + draft.Locations = []model.Locations{} - if err := e.client.AppDefinitions.Upsert(e.organizationId, draft); err != nil { + if err := e.client.AppDefinitions().Upsert(ctx, draft); err != nil { diagnostics.AddError("Error upsert app_definition definition", err.Error()) return true } - upload, err := e.client.AppUpload.Create(e.organizationId, defaultDummyBundle) + upload, err := e.clientAppUpload.AppUpload.Create(e.organizationId, defaultDummyBundle) if err != nil { diagnostics.AddError("Error uploading default bundle", err.Error()) @@ -212,7 +216,7 @@ func (e *appDefinitionResource) setDefaultBundle(plan *AppDefinition, diagnostic draft.Locations = locations - bundle, err := e.client.AppBundle.Create(e.organizationId, draft.Sys.ID, "Default Terraform BundleId", upload.Sys.ID) + bundle, err := e.clientAppUpload.AppBundle.Create(e.organizationId, draft.Sys.ID, "Default Terraform BundleId", upload.Sys.ID) if err != nil { diagnostics.AddError("Error creating app_bundle for app definition", err.Error()) return true @@ -238,7 +242,7 @@ func (e *appDefinitionResource) Read(ctx context.Context, request resource.ReadR func (e *appDefinitionResource) doRead(ctx context.Context, app *AppDefinition, state *tfsdk.State, d *diag.Diagnostics) { - appDefinition, err := e.getApp(app) + appDefinition, err := e.getApp(ctx, app) if err != nil { d.AddError( "Error reading app definition", @@ -273,7 +277,7 @@ func (e *appDefinitionResource) Update(ctx context.Context, request resource.Upd return } - appDefinition, err := e.getApp(plan) + appDefinition, err := e.getApp(ctx, plan) if err != nil { response.Diagnostics.AddError( "Error reading app definition", @@ -284,13 +288,13 @@ func (e *appDefinitionResource) Update(ctx context.Context, request resource.Upd if !plan.Equal(appDefinition) { - if e.setDefaultBundle(plan, response.Diagnostics) { + if e.setDefaultBundle(ctx, plan, response.Diagnostics) { return } draft := plan.Draft() - if err = e.client.AppDefinitions.Upsert(e.organizationId, draft); err != nil { + if err = e.client.AppDefinitions().Upsert(ctx, draft); err != nil { response.Diagnostics.AddError( "Error updating app definition", "Could not update app definition, unexpected error: "+err.Error(), @@ -307,7 +311,7 @@ func (e *appDefinitionResource) Delete(ctx context.Context, request resource.Del var state *AppDefinition response.Diagnostics.Append(request.State.Get(ctx, &state)...) - if err := e.client.AppDefinitions.Delete(e.organizationId, state.ID.ValueString()); err != nil { + if err := e.client.AppDefinitions().Delete(ctx, state.Draft()); err != nil { response.Diagnostics.AddError( "Error deleting app_definition definition", "Could not delete app_definition definition, unexpected error: "+err.Error(), @@ -325,6 +329,6 @@ func (e *appDefinitionResource) ImportState(ctx context.Context, request resourc e.doRead(ctx, futureState, &response.State, &response.Diagnostics) } -func (e *appDefinitionResource) getApp(app *AppDefinition) (*contentful.AppDefinition, error) { - return e.client.AppDefinitions.Get(e.organizationId, app.ID.ValueString()) +func (e *appDefinitionResource) getApp(ctx context.Context, app *AppDefinition) (*model.AppDefinition, error) { + return e.client.AppDefinitions().Get(ctx, app.ID.ValueString()) } diff --git a/internal/resources/app_definition/resource_test.go b/internal/resources/app_definition/resource_test.go index 6842013..72f1b37 100644 --- a/internal/resources/app_definition/resource_test.go +++ b/internal/resources/app_definition/resource_test.go @@ -1,9 +1,11 @@ package app_definition_test import ( + "context" "errors" "fmt" - "github.com/flaconi/contentful-go" + "github.com/flaconi/contentful-go/pkgs/common" + "github.com/flaconi/contentful-go/pkgs/model" "github.com/flaconi/terraform-provider-contentful/internal/acctest" "github.com/flaconi/terraform-provider-contentful/internal/provider" "github.com/flaconi/terraform-provider-contentful/internal/utils" @@ -17,7 +19,7 @@ import ( "testing" ) -type assertFunc func(*testing.T, *contentful.AppDefinition) +type assertFunc func(*testing.T, *model.AppDefinition) func TestAppDefinitionResource_Create(t *testing.T) { resourceName := "contentful_app_definition.acctest_app_definition" @@ -34,7 +36,7 @@ func TestAppDefinitionResource_Create(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "name", "tf_test1"), resource.TestMatchResourceAttr(resourceName, "id", regexp.MustCompile(`^[a-zA-Z0-9-_.]{1,64}$`)), resource.TestMatchResourceAttr(resourceName, "bundle_id", regexp.MustCompile(`^[a-zA-Z0-9-_.]{1,64}$`)), - testAccCheckContentfulAppDefinitionExists(t, resourceName, func(t *testing.T, definition *contentful.AppDefinition) { + testAccCheckContentfulAppDefinitionExists(t, resourceName, func(t *testing.T, definition *model.AppDefinition) { assert.Nil(t, definition.SRC) assert.EqualValues(t, definition.Name, "tf_test1") assert.Len(t, definition.Locations, 1) @@ -52,7 +54,7 @@ func TestAppDefinitionResource_Create(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "name", "tf_test1"), resource.TestMatchResourceAttr(resourceName, "id", regexp.MustCompile(`^[a-zA-Z0-9-_.]{1,64}$`)), resource.TestMatchResourceAttr(resourceName, "bundle_id", regexp.MustCompile(`^[a-zA-Z0-9-_.]{1,64}$`)), - testAccCheckContentfulAppDefinitionExists(t, resourceName, func(t *testing.T, definition *contentful.AppDefinition) { + testAccCheckContentfulAppDefinitionExists(t, resourceName, func(t *testing.T, definition *model.AppDefinition) { assert.Nil(t, definition.SRC) assert.EqualValues(t, definition.Name, "tf_test1") assert.Len(t, definition.Locations, 2) @@ -71,7 +73,7 @@ func TestAppDefinitionResource_Create(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "name", "tf_test1"), resource.TestCheckResourceAttr(resourceName, "src", "http://localhost"), resource.TestCheckNoResourceAttr(resourceName, "bundle_id"), - testAccCheckContentfulAppDefinitionExists(t, resourceName, func(t *testing.T, definition *contentful.AppDefinition) { + testAccCheckContentfulAppDefinitionExists(t, resourceName, func(t *testing.T, definition *model.AppDefinition) { assert.Equal(t, *definition.SRC, "http://localhost") assert.EqualValues(t, definition.Name, "tf_test1") assert.Len(t, definition.Locations, 1) @@ -98,7 +100,7 @@ func testAccCheckContentfulAppDefinitionExists(t *testing.T, resourceName string } } -func getAppDefinitionFromState(s *terraform.State, resourceName string) (*contentful.AppDefinition, error) { +func getAppDefinitionFromState(s *terraform.State, resourceName string) (*model.AppDefinition, error) { rs, ok := s.RootModule().Resources[resourceName] if !ok { return nil, fmt.Errorf("app definition not found") @@ -108,21 +110,22 @@ func getAppDefinitionFromState(s *terraform.State, resourceName string) (*conten return nil, fmt.Errorf("no app definition ID found") } - client := acctest.GetClient() + client := acctest.GetCMA() - return client.AppDefinitions.Get(os.Getenv("CONTENTFUL_ORGANIZATION_ID"), rs.Primary.ID) + return client.WithOrganizationId(os.Getenv("CONTENTFUL_ORGANIZATION_ID")).AppDefinitions().Get(context.Background(), rs.Primary.ID) } func testAccCheckContentfulAppDefinitionDestroy(s *terraform.State) error { - client := acctest.GetClient() + client := acctest.GetCMA() for _, rs := range s.RootModule().Resources { if rs.Type != "contentful_app_definition" { continue } - _, err := client.AppDefinitions.Get(os.Getenv("CONTENTFUL_ORGANIZATION_ID"), rs.Primary.ID) - var notFoundError contentful.NotFoundError + _, err := client.WithOrganizationId(os.Getenv("CONTENTFUL_ORGANIZATION_ID")).AppDefinitions().Get(context.Background(), rs.Primary.ID) + + var notFoundError common.NotFoundError if errors.As(err, ¬FoundError) { return nil } diff --git a/internal/resources/app_installation/resource.go b/internal/resources/app_installation/resource.go index 8b856b9..01711ea 100644 --- a/internal/resources/app_installation/resource.go +++ b/internal/resources/app_installation/resource.go @@ -5,9 +5,9 @@ import ( _ "embed" "errors" "fmt" - "github.com/flaconi/contentful-go" + "github.com/flaconi/contentful-go/pkgs/common" "github.com/flaconi/contentful-go/pkgs/model" - "github.com/flaconi/contentful-go/service/common" + "github.com/flaconi/contentful-go/service/cma" "github.com/flaconi/terraform-provider-contentful/internal/utils" "github.com/hashicorp/terraform-plugin-framework-jsontypes/jsontypes" "github.com/hashicorp/terraform-plugin-framework/diag" @@ -33,7 +33,7 @@ func NewAppInstallationResource() resource.Resource { // appInstallationResource is the resource implementation. type appInstallationResource struct { - client common.SpaceIdClientBuilder + client cma.SpaceIdClientBuilder organizationId string } @@ -103,7 +103,7 @@ func (e *appInstallationResource) Create(ctx context.Context, request resource.C draft := plan.Draft() if err := e.client.WithSpaceId(plan.SpaceId.ValueString()).WithEnvironment(plan.Environment.ValueString()).AppInstallations().Upsert(ctx, draft); err != nil { - var errorResponse contentful.ErrorResponse + var errorResponse common.ErrorResponse if errors.As(err, &errorResponse) { if errorResponse.Error() == "Forbidden" { response.Diagnostics.AddError("Error creating app_installation", fmt.Sprintf("%s: %s", errorResponse.Error(), errorResponse.Details.Reasons)) diff --git a/internal/resources/contenttype/model.go b/internal/resources/contenttype/model.go index b087c67..ff01050 100644 --- a/internal/resources/contenttype/model.go +++ b/internal/resources/contenttype/model.go @@ -5,6 +5,7 @@ import ( "fmt" "github.com/elliotchance/pie/v2" "github.com/flaconi/contentful-go" + "github.com/flaconi/contentful-go/pkgs/model" "github.com/flaconi/terraform-provider-contentful/internal/utils" "github.com/hashicorp/terraform-plugin-framework-jsontypes/jsontypes" "github.com/hashicorp/terraform-plugin-framework/attr" @@ -94,17 +95,17 @@ type Validation struct { Message types.String `tfsdk:"message"` } -func (v Validation) Draft() contentful.FieldValidation { +func (v Validation) Draft() model.FieldValidation { if !v.Unique.IsUnknown() && !v.Unique.IsNull() { - return contentful.FieldValidationUnique{ + return model.FieldValidationUnique{ Unique: v.Unique.ValueBool(), } } if v.Size != nil { - return contentful.FieldValidationSize{ - Size: &contentful.MinMax{ + return model.FieldValidationSize{ + Size: &model.MinMax{ Min: v.Size.Min.ValueFloat64Pointer(), Max: v.Size.Max.ValueFloat64Pointer(), }, @@ -113,8 +114,8 @@ func (v Validation) Draft() contentful.FieldValidation { } if v.Range != nil { - return contentful.FieldValidationRange{ - Range: &contentful.MinMax{ + return model.FieldValidationRange{ + Range: &model.MinMax{ Min: v.Range.Min.ValueFloat64Pointer(), Max: v.Range.Max.ValueFloat64Pointer(), }, @@ -123,8 +124,8 @@ func (v Validation) Draft() contentful.FieldValidation { } if v.AssetFileSize != nil { - return contentful.FieldValidationFileSize{ - Size: &contentful.MinMax{ + return model.FieldValidationFileSize{ + Size: &model.MinMax{ Min: v.AssetFileSize.Min.ValueFloat64Pointer(), Max: v.AssetFileSize.Max.ValueFloat64Pointer(), }, @@ -132,8 +133,8 @@ func (v Validation) Draft() contentful.FieldValidation { } if v.Regexp != nil { - return contentful.FieldValidationRegex{ - Regex: &contentful.Regex{ + return model.FieldValidationRegex{ + Regex: &model.Regex{ Pattern: v.Regexp.Pattern.ValueString(), }, ErrorMessage: v.Message.ValueStringPointer(), @@ -141,7 +142,7 @@ func (v Validation) Draft() contentful.FieldValidation { } if len(v.LinkContentType) > 0 { - return contentful.FieldValidationLink{ + return model.FieldValidationLink{ LinkContentType: pie.Map(v.LinkContentType, func(t types.String) string { return t.ValueString() }), @@ -149,7 +150,7 @@ func (v Validation) Draft() contentful.FieldValidation { } if len(v.LinkMimetypeGroup) > 0 { - return contentful.FieldValidationMimeType{ + return model.FieldValidationMimeType{ MimeTypes: pie.Map(v.LinkMimetypeGroup, func(t types.String) string { return t.ValueString() }), @@ -158,7 +159,7 @@ func (v Validation) Draft() contentful.FieldValidation { } if len(v.In) > 0 { - return contentful.FieldValidationPredefinedValues{ + return model.FieldValidationPredefinedValues{ In: pie.Map(v.In, func(t types.String) any { return t.ValueString() }), @@ -166,7 +167,7 @@ func (v Validation) Draft() contentful.FieldValidation { } if len(v.EnabledMarks) > 0 { - return contentful.FieldValidationEnabledMarks{ + return model.FieldValidationEnabledMarks{ Marks: pie.Map(v.EnabledMarks, func(t types.String) string { return t.ValueString() }), @@ -175,7 +176,7 @@ func (v Validation) Draft() contentful.FieldValidation { } if len(v.EnabledNodeTypes) > 0 { - return contentful.FieldValidationEnabledNodeTypes{ + return model.FieldValidationEnabledNodeTypes{ NodeTypes: pie.Map(v.EnabledNodeTypes, func(t types.String) string { return t.ValueString() }), @@ -195,7 +196,7 @@ type Regexp struct { Pattern types.String `tfsdk:"pattern"` } -func (f *Field) Equal(n *contentful.Field) bool { +func (f *Field) Equal(n *model.Field) bool { if n.Type != f.Type.ValueString() { return false @@ -241,7 +242,7 @@ func (f *Field) Equal(n *contentful.Field) bool { return false } - for idx, validation := range pie.Map(f.Validations, func(t Validation) contentful.FieldValidation { + for idx, validation := range pie.Map(f.Validations, func(t Validation) model.FieldValidation { return t.Draft() }) { cfVal := n.Validations[idx] @@ -259,9 +260,9 @@ func (f *Field) Equal(n *contentful.Field) bool { return true } -func (f *Field) ToNative() (*contentful.Field, error) { +func (f *Field) ToNative() (*model.Field, error) { - contentfulField := &contentful.Field{ + contentfulField := &model.Field{ ID: f.Id.ValueString(), Name: f.Name.ValueString(), Type: f.Type.ValueString(), @@ -269,7 +270,7 @@ func (f *Field) ToNative() (*contentful.Field, error) { Required: f.Required.ValueBool(), Disabled: f.Disabled.ValueBool(), Omitted: f.Omitted.ValueBool(), - Validations: pie.Map(f.Validations, func(t Validation) contentful.FieldValidation { + Validations: pie.Map(f.Validations, func(t Validation) model.FieldValidation { return t.Draft() }), } @@ -278,7 +279,7 @@ func (f *Field) ToNative() (*contentful.Field, error) { contentfulField.LinkType = f.LinkType.ValueString() } - if contentfulField.Type == contentful.FieldTypeArray { + if contentfulField.Type == model.FieldTypeArray { items, errItem := f.Items.ToNative() if errItem != nil { @@ -312,7 +313,7 @@ func getTypeOfMap(mapValues map[string]any) (*string, error) { return nil, nil } -func (f *Field) Import(n *contentful.Field, c []contentful.Controls) error { +func (f *Field) Import(n *model.Field, c []contentful.Controls) error { f.Id = types.StringValue(n.ID) f.Name = types.StringValue(n.Name) f.Type = types.StringValue(n.Type) @@ -364,7 +365,7 @@ func (f *Field) Import(n *contentful.Field, c []contentful.Controls) error { f.Validations = validations - if n.Type == contentful.FieldTypeArray { + if n.Type == model.FieldTypeArray { itemValidations, err := getValidations(n.Items.Validations) @@ -445,18 +446,18 @@ type Items struct { Validations []Validation `tfsdk:"validations"` } -func (i *Items) ToNative() (*contentful.FieldTypeArrayItem, error) { +func (i *Items) ToNative() (*model.FieldTypeArrayItem, error) { - return &contentful.FieldTypeArrayItem{ + return &model.FieldTypeArrayItem{ Type: i.Type.ValueString(), - Validations: pie.Map(i.Validations, func(t Validation) contentful.FieldValidation { + Validations: pie.Map(i.Validations, func(t Validation) model.FieldValidation { return t.Draft() }), LinkType: i.LinkType.ValueStringPointer(), }, nil } -func (i *Items) Equal(n *contentful.FieldTypeArrayItem) bool { +func (i *Items) Equal(n *model.FieldTypeArrayItem) bool { if n == nil { return false @@ -474,7 +475,7 @@ func (i *Items) Equal(n *contentful.FieldTypeArrayItem) bool { return false } - for idx, validation := range pie.Map(i.Validations, func(t Validation) contentful.FieldValidation { + for idx, validation := range pie.Map(i.Validations, func(t Validation) model.FieldValidation { return t.Draft() }) { cfVal := n.Validations[idx] @@ -488,9 +489,9 @@ func (i *Items) Equal(n *contentful.FieldTypeArrayItem) bool { return true } -func (c *ContentType) Draft() (*contentful.ContentType, error) { +func (c *ContentType) Draft() (*model.ContentType, error) { - var fields []*contentful.Field + var fields []*model.Field for _, field := range c.Fields { @@ -502,14 +503,22 @@ func (c *ContentType) Draft() (*contentful.ContentType, error) { fields = append(fields, nativeField) } - contentfulType := &contentful.ContentType{ + contentfulType := &model.ContentType{ Name: c.Name.ValueString(), DisplayField: c.DisplayField.ValueString(), Fields: fields, } if !c.ID.IsUnknown() || !c.ID.IsNull() { - contentfulType.Sys = &contentful.Sys{ID: c.ID.ValueString()} + contentfulType.Sys = &model.EnvironmentSys{ + SpaceSys: model.SpaceSys{ + CreatedSys: model.CreatedSys{ + BaseSys: model.BaseSys{ + ID: c.ID.ValueString(), + }, + }, + }, + } } if !c.Description.IsNull() && !c.Description.IsUnknown() { @@ -520,7 +529,7 @@ func (c *ContentType) Draft() (*contentful.ContentType, error) { } -func (c *ContentType) Import(n *contentful.ContentType, e *contentful.EditorInterface) error { +func (c *ContentType) Import(n *model.ContentType, e *contentful.EditorInterface) error { c.ID = types.StringValue(n.Sys.ID) c.Version = types.Int64Value(int64(n.Sys.Version)) @@ -571,7 +580,7 @@ func (c *ContentType) Import(n *contentful.ContentType, e *contentful.EditorInte } -func (c *ContentType) Equal(n *contentful.ContentType) bool { +func (c *ContentType) Equal(n *model.ContentType) bool { if !utils.CompareStringPointer(c.Description, n.Description) { return false @@ -590,7 +599,7 @@ func (c *ContentType) Equal(n *contentful.ContentType) bool { } for idxOrg, field := range c.Fields { - idx := pie.FindFirstUsing(n.Fields, func(f *contentful.Field) bool { + idx := pie.FindFirstUsing(n.Fields, func(f *model.Field) bool { return f.ID == field.Id.ValueString() }) @@ -739,7 +748,7 @@ func (c *ContentType) DraftEditorInterface(n *contentful.EditorInterface) { }) } -func getValidations(contentfulValidations []contentful.FieldValidation) ([]Validation, error) { +func getValidations(contentfulValidations []model.FieldValidation) ([]Validation, error) { var validations []Validation for _, validation := range contentfulValidations { @@ -756,9 +765,9 @@ func getValidations(contentfulValidations []contentful.FieldValidation) ([]Valid return validations, nil } -func getValidation(cfVal contentful.FieldValidation) (*Validation, error) { +func getValidation(cfVal model.FieldValidation) (*Validation, error) { - if v, ok := cfVal.(contentful.FieldValidationPredefinedValues); ok { + if v, ok := cfVal.(model.FieldValidationPredefinedValues); ok { return &Validation{ In: pie.Map(v.In, func(t any) types.String { @@ -767,14 +776,14 @@ func getValidation(cfVal contentful.FieldValidation) (*Validation, error) { }, nil } - if v, ok := cfVal.(contentful.FieldValidationUnique); ok { + if v, ok := cfVal.(model.FieldValidationUnique); ok { return &Validation{ Unique: types.BoolValue(v.Unique), }, nil } - if v, ok := cfVal.(contentful.FieldValidationRegex); ok { + if v, ok := cfVal.(model.FieldValidationRegex); ok { return &Validation{ Regexp: &Regexp{ @@ -784,7 +793,7 @@ func getValidation(cfVal contentful.FieldValidation) (*Validation, error) { }, nil } - if v, ok := cfVal.(contentful.FieldValidationSize); ok { + if v, ok := cfVal.(model.FieldValidationSize); ok { return &Validation{ Size: &Size{ @@ -794,7 +803,7 @@ func getValidation(cfVal contentful.FieldValidation) (*Validation, error) { }, nil } - if v, ok := cfVal.(contentful.FieldValidationLink); ok { + if v, ok := cfVal.(model.FieldValidationLink); ok { return &Validation{ LinkContentType: pie.Map(v.LinkContentType, func(t string) types.String { @@ -803,7 +812,7 @@ func getValidation(cfVal contentful.FieldValidation) (*Validation, error) { }, nil } - if v, ok := cfVal.(contentful.FieldValidationMimeType); ok { + if v, ok := cfVal.(model.FieldValidationMimeType); ok { return &Validation{ LinkMimetypeGroup: pie.Map(v.MimeTypes, func(t string) types.String { @@ -813,7 +822,7 @@ func getValidation(cfVal contentful.FieldValidation) (*Validation, error) { }, nil } - if v, ok := cfVal.(contentful.FieldValidationRange); ok { + if v, ok := cfVal.(model.FieldValidationRange); ok { return &Validation{ Range: &Size{ @@ -823,7 +832,7 @@ func getValidation(cfVal contentful.FieldValidation) (*Validation, error) { }, nil } - if v, ok := cfVal.(contentful.FieldValidationEnabledNodeTypes); ok { + if v, ok := cfVal.(model.FieldValidationEnabledNodeTypes); ok { return &Validation{ EnabledNodeTypes: pie.Map(v.NodeTypes, func(t string) types.String { @@ -833,7 +842,7 @@ func getValidation(cfVal contentful.FieldValidation) (*Validation, error) { }, nil } - if v, ok := cfVal.(contentful.FieldValidationEnabledMarks); ok { + if v, ok := cfVal.(model.FieldValidationEnabledMarks); ok { return &Validation{ EnabledMarks: pie.Map(v.Marks, func(t string) types.String { @@ -843,7 +852,7 @@ func getValidation(cfVal contentful.FieldValidation) (*Validation, error) { }, nil } - if v, ok := cfVal.(contentful.FieldValidationFileSize); ok { + if v, ok := cfVal.(model.FieldValidationFileSize); ok { return &Validation{ AssetFileSize: &Size{ Max: types.Float64PointerValue(v.Size.Max), diff --git a/internal/resources/contenttype/resource.go b/internal/resources/contenttype/resource.go index e41eff3..1d0baec 100644 --- a/internal/resources/contenttype/resource.go +++ b/internal/resources/contenttype/resource.go @@ -5,6 +5,8 @@ import ( "fmt" "github.com/elliotchance/pie/v2" "github.com/flaconi/contentful-go" + "github.com/flaconi/contentful-go/pkgs/model" + "github.com/flaconi/contentful-go/service/cma" "github.com/flaconi/terraform-provider-contentful/internal/custommodifier" "github.com/flaconi/terraform-provider-contentful/internal/customvalidator" "github.com/flaconi/terraform-provider-contentful/internal/utils" @@ -45,7 +47,8 @@ func NewContentTypeResource() resource.Resource { // contentTypeResource is the resource implementation. type contentTypeResource struct { - client *contentful.Client + client cma.SpaceIdClientBuilder + clientOld *contentful.Client } func (e *contentTypeResource) Metadata(_ context.Context, request resource.MetadataRequest, response *resource.MetadataResponse) { @@ -147,7 +150,7 @@ func (e *contentTypeResource) Schema(ctx context.Context, request resource.Schem Description: "space id", }, "environment": schema.StringAttribute{ - Optional: true, + Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.RequiresReplace(), }, @@ -171,6 +174,7 @@ func (e *contentTypeResource) Schema(ctx context.Context, request resource.Schem "fields": schema.ListNestedAttribute{ Validators: []validator.List{ listvalidator.SizeAtLeast(1), + listvalidator.UniqueValues(), }, Required: true, NestedObject: schema.NestedAttributeObject{ @@ -375,7 +379,8 @@ func (e *contentTypeResource) Configure(_ context.Context, request resource.Conf } data := request.ProviderData.(utils.ProviderData) - e.client = data.Client + e.client = data.CMAClient + e.clientOld = data.Client } @@ -393,34 +398,16 @@ func (e *contentTypeResource) Create(ctx context.Context, request resource.Creat return } - if plan.Environment.IsUnknown() || plan.Environment.IsNull() { - if err = e.client.ContentTypes.Upsert(plan.SpaceId.ValueString(), draft); err != nil { - response.Diagnostics.AddError("Error creating contenttype", err.Error()) - return - } - - if err = e.client.ContentTypes.Activate(plan.SpaceId.ValueString(), draft); err != nil { - response.Diagnostics.AddError("Error activating contenttype", err.Error()) - return - } - } else { - - env := &contentful.Environment{Sys: &contentful.Sys{ - ID: plan.Environment.ValueString(), - Space: &contentful.Space{ - Sys: &contentful.Sys{ID: plan.SpaceId.ValueString()}, - }, - }} + envClient := e.client.WithSpaceId(plan.SpaceId.ValueString()).WithEnvironment(plan.Environment.ValueString()) - if err = e.client.ContentTypes.UpsertWithEnv(env, draft); err != nil { - response.Diagnostics.AddError("Error creating contenttype", err.Error()) - return - } + if err = envClient.ContentTypes().Upsert(ctx, draft); err != nil { + response.Diagnostics.AddError("Error creating contenttype", err.Error()) + return + } - if err = e.client.ContentTypes.ActivateWithEnv(env, draft); err != nil { - response.Diagnostics.AddError("Error activating contenttype", err.Error()) - return - } + if err = envClient.ContentTypes().Activate(ctx, draft); err != nil { + response.Diagnostics.AddError("Error activating contenttype", err.Error()) + return } plan.Version = types.Int64Value(int64(draft.Sys.Version)) @@ -448,7 +435,7 @@ func (e *contentTypeResource) Read(ctx context.Context, request resource.ReadReq func (e *contentTypeResource) doRead(ctx context.Context, contentType *ContentType, state *tfsdk.State, d *diag.Diagnostics) { - contentfulContentType, err := e.getContentType(contentType) + contentfulContentType, err := e.getContentType(ctx, contentType) if err != nil { d.AddError( "Error reading contenttype", @@ -517,7 +504,7 @@ func (e *contentTypeResource) Update(ctx context.Context, request resource.Updat return } - contentfulContentType, err := e.getContentType(plan) + contentfulContentType, err := e.getContentType(ctx, plan) if err != nil { response.Diagnostics.AddError( "Error reading contenttype", @@ -526,12 +513,12 @@ func (e *contentTypeResource) Update(ctx context.Context, request resource.Updat return } - deletedFields := pie.Of(pie.FilterNot(contentfulContentType.Fields, func(cf *contentful.Field) bool { + deletedFields := pie.Of(pie.FilterNot(contentfulContentType.Fields, func(cf *model.Field) bool { return pie.FindFirstUsing(plan.Fields, func(f Field) bool { return cf.ID == f.Id.ValueString() }) != -1 - })).Map(func(f *contentful.Field) *contentful.Field { + })).Map(func(f *model.Field) *model.Field { f.Omitted = true return f @@ -555,11 +542,11 @@ func (e *contentTypeResource) Update(ctx context.Context, request resource.Updat // followed by the field removal and final publish. if !plan.Equal(contentfulContentType) { - err = e.doUpdate(plan, draft) + err = e.doUpdate(ctx, plan, draft) if err != nil { response.Diagnostics.AddError( - "Error updating subscription", - "Could not update subscription, unexpected error: "+err.Error(), + "Error updating contenttype", + "Could not update contenttype, unexpected error: "+err.Error(), ) return } @@ -575,11 +562,11 @@ func (e *contentTypeResource) Update(ctx context.Context, request resource.Updat draft.Sys = sys - err = e.doUpdate(plan, draft) + err = e.doUpdate(ctx, plan, draft) if err != nil { response.Diagnostics.AddError( - "Error updating subscription", - "Could not update subscription, unexpected error: "+err.Error(), + "Error updating contenttype", + "Could not update contenttype, unexpected error: "+err.Error(), ) return } @@ -610,11 +597,9 @@ func (e *contentTypeResource) updateEditorInterface(ctx context.Context, state * if !plan.EqualEditorInterface(editorInterface) { plan.DraftEditorInterface(editorInterface) - if !plan.Environment.IsUnknown() && !plan.Environment.IsNull() { - e.client.SetEnvironment(plan.Environment.ValueString()) - } + e.clientOld.SetEnvironment(plan.Environment.ValueString()) - if err = e.client.EditorInterfaces.Update(plan.SpaceId.ValueString(), plan.ID.ValueString(), editorInterface); err != nil { + if err = e.clientOld.EditorInterfaces.Update(plan.SpaceId.ValueString(), plan.ID.ValueString(), editorInterface); err != nil { d.AddError( "Error updating contenttype editorInterface", "Could not update contenttype editorInterface, unexpected error: "+err.Error(), @@ -629,34 +614,14 @@ func (e *contentTypeResource) updateEditorInterface(ctx context.Context, state * return ctx } -func (e *contentTypeResource) doUpdate(plan *ContentType, draft *contentful.ContentType) error { - if plan.Environment.IsUnknown() || plan.Environment.IsNull() { - - if err := e.client.ContentTypes.Upsert(plan.SpaceId.ValueString(), draft); err != nil { - return err - } - - if err := e.client.ContentTypes.Activate(plan.SpaceId.ValueString(), draft); err != nil { - return err - } - } else { - - env := &contentful.Environment{Sys: &contentful.Sys{ - ID: plan.Environment.ValueString(), - Space: &contentful.Space{ - Sys: &contentful.Sys{ID: plan.SpaceId.ValueString()}, - }, - }} - - if err := e.client.ContentTypes.UpsertWithEnv(env, draft); err != nil { - return err - } +func (e *contentTypeResource) doUpdate(ctx context.Context, plan *ContentType, draft *model.ContentType) error { + envClient := e.client.WithSpaceId(plan.SpaceId.ValueString()).WithEnvironment(plan.Environment.ValueString()) - if err := e.client.ContentTypes.ActivateWithEnv(env, draft); err != nil { - return err - } + if err := envClient.ContentTypes().Upsert(ctx, draft); err != nil { + return err } - return nil + + return envClient.ContentTypes().Activate(ctx, draft) } func (e *contentTypeResource) Delete(ctx context.Context, request resource.DeleteRequest, response *resource.DeleteResponse) { @@ -664,7 +629,7 @@ func (e *contentTypeResource) Delete(ctx context.Context, request resource.Delet var state *ContentType response.Diagnostics.Append(request.State.Get(ctx, &state)...) - contentfulContentType, err := e.getContentType(state) + contentfulContentType, err := e.getContentType(ctx, state) if err != nil { response.Diagnostics.AddError( @@ -674,7 +639,7 @@ func (e *contentTypeResource) Delete(ctx context.Context, request resource.Delet return } - err = e.doDelete(state, contentfulContentType) + err = e.doDelete(ctx, state, contentfulContentType) if err != nil { response.Diagnostics.AddError( "Error deleting contenttype", @@ -685,35 +650,14 @@ func (e *contentTypeResource) Delete(ctx context.Context, request resource.Delet } -func (e *contentTypeResource) doDelete(data *ContentType, draft *contentful.ContentType) error { - if data.Environment.IsUnknown() || data.Environment.IsNull() { - - if err := e.client.ContentTypes.Deactivate(data.SpaceId.ValueString(), draft); err != nil { - return err - } - - if err := e.client.ContentTypes.Delete(data.SpaceId.ValueString(), draft); err != nil { - return err - } - } else { - - env := &contentful.Environment{Sys: &contentful.Sys{ - ID: data.Environment.ValueString(), - Space: &contentful.Space{ - Sys: &contentful.Sys{ID: data.SpaceId.ValueString()}, - }, - }} - - if err := e.client.ContentTypes.DeactivateWithEnv(env, draft); err != nil { - return err - } - - if err := e.client.ContentTypes.DeleteWithEnv(env, draft); err != nil { - return err - } +func (e *contentTypeResource) doDelete(ctx context.Context, data *ContentType, draft *model.ContentType) error { + envClient := e.client.WithSpaceId(data.SpaceId.ValueString()).WithEnvironment(data.Environment.ValueString()) + if err := envClient.ContentTypes().Deactivate(ctx, draft); err != nil { + return err } - return nil + + return envClient.ContentTypes().Delete(ctx, draft) } func (e *contentTypeResource) ImportState(ctx context.Context, request resource.ImportStateRequest, response *resource.ImportStateResponse) { @@ -736,34 +680,21 @@ func (e *contentTypeResource) ImportState(ctx context.Context, request resource. e.doRead(ctx, futureState, &response.State, &response.Diagnostics) } -func (e *contentTypeResource) getContentType(editor *ContentType) (*contentful.ContentType, error) { - if !editor.Environment.IsUnknown() && !editor.Environment.IsNull() { - - env := &contentful.Environment{Sys: &contentful.Sys{ - ID: editor.Environment.ValueString(), - Space: &contentful.Space{ - Sys: &contentful.Sys{ID: editor.SpaceId.ValueString()}, - }, - }} +func (e *contentTypeResource) getContentType(ctx context.Context, editor *ContentType) (*model.ContentType, error) { + envClient := e.client.WithSpaceId(editor.SpaceId.ValueString()).WithEnvironment(editor.Environment.ValueString()) - return e.client.ContentTypes.GetWithEnv(env, editor.ID.ValueString()) - } else { - return e.client.ContentTypes.Get(editor.SpaceId.ValueString(), editor.ID.ValueString()) - } + return envClient.ContentTypes().Get(ctx, editor.ID.ValueString()) } func (e *contentTypeResource) getEditorInterface(editor *ContentType) (*contentful.EditorInterface, error) { - if !editor.Environment.IsUnknown() && !editor.Environment.IsNull() { - env := &contentful.Environment{Sys: &contentful.Sys{ - ID: editor.Environment.ValueString(), - Space: &contentful.Space{ - Sys: &contentful.Sys{ID: editor.SpaceId.ValueString()}, - }, - }} + env := &contentful.Environment{Sys: &contentful.Sys{ + ID: editor.Environment.ValueString(), + Space: &contentful.Space{ + Sys: &contentful.Sys{ID: editor.SpaceId.ValueString()}, + }, + }} + + return e.clientOld.EditorInterfaces.GetWithEnv(env, editor.ID.ValueString()) - return e.client.EditorInterfaces.GetWithEnv(env, editor.ID.ValueString()) - } else { - return e.client.EditorInterfaces.Get(editor.SpaceId.ValueString(), editor.ID.ValueString()) - } } diff --git a/internal/resources/contenttype/resource_test.go b/internal/resources/contenttype/resource_test.go index cd8bdbc..4659944 100644 --- a/internal/resources/contenttype/resource_test.go +++ b/internal/resources/contenttype/resource_test.go @@ -1,9 +1,12 @@ package contenttype_test import ( + "context" "errors" "fmt" "github.com/flaconi/contentful-go" + "github.com/flaconi/contentful-go/pkgs/common" + "github.com/flaconi/contentful-go/pkgs/model" "github.com/flaconi/terraform-provider-contentful/internal/acctest" "github.com/flaconi/terraform-provider-contentful/internal/provider" "github.com/flaconi/terraform-provider-contentful/internal/utils" @@ -13,11 +16,12 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" "github.com/stretchr/testify/assert" "os" + "regexp" "testing" ) -type assertFunc func(*testing.T, *contentful.ContentType) +type assertFunc func(*testing.T, *model.ContentType) type assertEditorInterfaceFunc func(*testing.T, *contentful.EditorInterface) func TestContentTypeResource_Create(t *testing.T) { @@ -37,14 +41,14 @@ func TestContentTypeResource_Create(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "id", "tf_test1"), resource.TestCheckResourceAttr(resourceName, "version", "2"), resource.TestCheckResourceAttr(resourceName, "version_controls", "0"), - testAccCheckContentfulContentTypeExists(t, resourceName, func(t *testing.T, contentType *contentful.ContentType) { + testAccCheckContentfulContentTypeExists(t, resourceName, func(t *testing.T, contentType *model.ContentType) { assert.EqualValues(t, "tf_test1", contentType.Name) assert.Equal(t, 2, contentType.Sys.Version) assert.EqualValues(t, "tf_test1", contentType.Sys.ID) assert.EqualValues(t, "none", *contentType.Description) assert.EqualValues(t, "field1", contentType.DisplayField) assert.Len(t, contentType.Fields, 2) - assert.Equal(t, &contentful.Field{ + assert.Equal(t, &model.Field{ ID: "field1", Name: "Field 1 name change", Type: "Text", @@ -57,7 +61,7 @@ func TestContentTypeResource_Create(t *testing.T) { Validations: nil, DefaultValue: nil, }, contentType.Fields[0]) - assert.Equal(t, &contentful.Field{ + assert.Equal(t, &model.Field{ ID: "field3", Name: "Field 3 new field", Type: "Integer", @@ -79,14 +83,14 @@ func TestContentTypeResource_Create(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "name", "tf_test1"), resource.TestCheckResourceAttr(resourceName, "version", "4"), resource.TestCheckResourceAttr(resourceName, "version_controls", "0"), - testAccCheckContentfulContentTypeExists(t, resourceName, func(t *testing.T, contentType *contentful.ContentType) { + testAccCheckContentfulContentTypeExists(t, resourceName, func(t *testing.T, contentType *model.ContentType) { assert.EqualValues(t, "tf_test1", contentType.Name) assert.Equal(t, 4, contentType.Sys.Version) assert.EqualValues(t, "tf_test1", contentType.Sys.ID) assert.EqualValues(t, "Terraform Acc Test Content Type description change", *contentType.Description) assert.EqualValues(t, "field1", contentType.DisplayField) assert.Len(t, contentType.Fields, 2) - assert.Equal(t, &contentful.Field{ + assert.Equal(t, &model.Field{ ID: "field1", Name: "Field 1 name change", Type: "Text", @@ -96,7 +100,7 @@ func TestContentTypeResource_Create(t *testing.T) { Disabled: false, Omitted: false, }, contentType.Fields[1]) - assert.Equal(t, &contentful.Field{ + assert.Equal(t, &model.Field{ ID: "field3", Name: "Field 3 new field", Type: "Integer", @@ -115,14 +119,14 @@ func TestContentTypeResource_Create(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "name", "tf_test1"), resource.TestCheckResourceAttr(resourceName, "version", "6"), resource.TestCheckResourceAttr(resourceName, "version_controls", "4"), - testAccCheckContentfulContentTypeExists(t, resourceName, func(t *testing.T, contentType *contentful.ContentType) { + testAccCheckContentfulContentTypeExists(t, resourceName, func(t *testing.T, contentType *model.ContentType) { assert.EqualValues(t, "tf_test1", contentType.Name) assert.Equal(t, 6, contentType.Sys.Version) assert.EqualValues(t, "tf_test1", contentType.Sys.ID) assert.EqualValues(t, "Terraform Acc Test Content Type description change", *contentType.Description) assert.EqualValues(t, "field1", contentType.DisplayField) assert.Len(t, contentType.Fields, 2) - assert.Equal(t, &contentful.Field{ + assert.Equal(t, &model.Field{ ID: "field1", Name: "Field 1 name change", Type: "Text", @@ -132,7 +136,7 @@ func TestContentTypeResource_Create(t *testing.T) { Disabled: false, Omitted: false, }, contentType.Fields[0]) - assert.Equal(t, &contentful.Field{ + assert.Equal(t, &model.Field{ ID: "field3", Name: "Field 3 new field", Type: "Integer", @@ -164,19 +168,19 @@ func TestContentTypeResource_Create(t *testing.T) { Config: testContentTypeLinkConfig("acctest_content_type", os.Getenv("CONTENTFUL_SPACE_ID"), "linked_content_type"), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(linkedResourceName, "name", "tf_linked"), - testAccCheckContentfulContentTypeExists(t, linkedResourceName, func(t *testing.T, contentType *contentful.ContentType) { + testAccCheckContentfulContentTypeExists(t, linkedResourceName, func(t *testing.T, contentType *model.ContentType) { assert.EqualValues(t, "tf_linked", contentType.Name) assert.Equal(t, 2, contentType.Sys.Version) assert.EqualValues(t, "tf_linked", contentType.Sys.ID) assert.EqualValues(t, "Terraform Acc Test Content Type with links", *contentType.Description) assert.EqualValues(t, "asset_field", contentType.DisplayField) assert.Len(t, contentType.Fields, 2) - assert.Equal(t, &contentful.Field{ + assert.Equal(t, &model.Field{ ID: "asset_field", Name: "Asset Field", Type: "Array", LinkType: "", - Items: &contentful.FieldTypeArrayItem{ + Items: &model.FieldTypeArrayItem{ Type: "Link", LinkType: toPointer("Asset"), }, @@ -185,7 +189,7 @@ func TestContentTypeResource_Create(t *testing.T) { Disabled: false, Omitted: false, }, contentType.Fields[0]) - assert.Equal(t, &contentful.Field{ + assert.Equal(t, &model.Field{ ID: "entry_link_field", Name: "Entry Link Field", Type: "Link", @@ -194,8 +198,8 @@ func TestContentTypeResource_Create(t *testing.T) { Localized: false, Disabled: false, Omitted: false, - Validations: []contentful.FieldValidation{ - contentful.FieldValidationLink{ + Validations: []model.FieldValidation{ + model.FieldValidationLink{ LinkContentType: []string{"tf_test1"}, }, }, @@ -208,14 +212,14 @@ func TestContentTypeResource_Create(t *testing.T) { Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(resourceName, "name", "tf_test1"), resource.TestCheckResourceAttr(resourceName, "id", "tf_test2"), - testAccCheckContentfulContentTypeExists(t, resourceName, func(t *testing.T, contentType *contentful.ContentType) { + testAccCheckContentfulContentTypeExists(t, resourceName, func(t *testing.T, contentType *model.ContentType) { assert.EqualValues(t, "tf_test1", contentType.Name) assert.Equal(t, 2, contentType.Sys.Version) assert.EqualValues(t, "tf_test2", contentType.Sys.ID) assert.EqualValues(t, "Terraform Acc Test Content Type description change", *contentType.Description) assert.EqualValues(t, "field1", contentType.DisplayField) assert.Len(t, contentType.Fields, 2) - assert.Equal(t, &contentful.Field{ + assert.Equal(t, &model.Field{ ID: "field1", Name: "Field 1 name change", Type: "Text", @@ -225,7 +229,7 @@ func TestContentTypeResource_Create(t *testing.T) { Disabled: false, Omitted: false, }, contentType.Fields[0]) - assert.Equal(t, &contentful.Field{ + assert.Equal(t, &model.Field{ ID: "field3", Name: "Field 3 new field", Type: "Integer", @@ -241,7 +245,25 @@ func TestContentTypeResource_Create(t *testing.T) { }, }) } -func getContentTypeFromState(s *terraform.State, resourceName string) (*contentful.ContentType, error) { + +func TestContentTypeResource_WithDuplicateField(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.TestAccPreCheck(t) }, + CheckDestroy: testAccCheckContentfulContentTypeDestroy, + ProtoV6ProviderFactories: map[string]func() (tfprotov6.ProviderServer, error){ + "contentful": providerserver.NewProtocol6WithError(provider.New("test", false)), + }, + Steps: []resource.TestStep{ + { + Config: testContentTypeDuplicateFields("acctest_content_type", os.Getenv("CONTENTFUL_SPACE_ID")), + PlanOnly: true, + ExpectError: regexp.MustCompile("Error: Duplicate List Value"), + }, + }, + }) +} + +func getContentTypeFromState(s *terraform.State, resourceName string) (*model.ContentType, error) { rs, ok := s.RootModule().Resources[resourceName] if !ok { return nil, fmt.Errorf("content type not found") @@ -251,9 +273,9 @@ func getContentTypeFromState(s *terraform.State, resourceName string) (*contentf return nil, fmt.Errorf("no content type ID found") } - client := acctest.GetClient() + client := acctest.GetCMA() - return client.ContentTypes.Get(os.Getenv("CONTENTFUL_SPACE_ID"), rs.Primary.ID) + return client.WithSpaceId(os.Getenv("CONTENTFUL_SPACE_ID")).WithEnvironment("master").ContentTypes().Get(context.Background(), rs.Primary.ID) } func getEditorInterfaceFromState(id string) (*contentful.EditorInterface, error) { @@ -287,7 +309,7 @@ func testAccCheckEditorInterfaceExists(t *testing.T, id string, assertFunc asser } func testAccCheckContentfulContentTypeDestroy(s *terraform.State) (err error) { - client := acctest.GetClient() + client := acctest.GetCMA() for _, rs := range s.RootModule().Resources { if rs.Type != "contentful_contenttype" { @@ -299,8 +321,8 @@ func testAccCheckContentfulContentTypeDestroy(s *terraform.State) (err error) { return fmt.Errorf("no space_id is set") } - _, err := client.ContentTypes.Get(spaceID, rs.Primary.ID) - var notFoundError contentful.NotFoundError + _, err := client.WithSpaceId(spaceID).WithEnvironment("master").ContentTypes().Get(context.Background(), rs.Primary.ID) + var notFoundError common.NotFoundError if errors.As(err, ¬FoundError) { return nil } @@ -343,6 +365,13 @@ func testContentTypeUpdate(identifier string, spaceId string) string { }) } +func testContentTypeDuplicateFields(identifier string, spaceId string) string { + return utils.HCLTemplateFromPath("test_resources/update_duplicate_field.tf", map[string]any{ + "identifier": identifier, + "spaceId": spaceId, + }) +} + func testContentTypeLinkConfig(identifier string, spaceId string, linkIdentifier string) string { return utils.HCLTemplateFromPath("test_resources/link_config.tf", map[string]any{ "identifier": identifier, diff --git a/internal/resources/contenttype/test_resources/changed_order.tf b/internal/resources/contenttype/test_resources/changed_order.tf index 4b3af8a..b84f2d7 100644 --- a/internal/resources/contenttype/test_resources/changed_order.tf +++ b/internal/resources/contenttype/test_resources/changed_order.tf @@ -1,5 +1,6 @@ resource "contentful_contenttype" "{{ .identifier }}" { space_id = "{{ .spaceId }}" + environment = "master" name = "tf_test1" description = "Terraform Acc Test Content Type description change" display_field = "field1" diff --git a/internal/resources/contenttype/test_resources/create.tf b/internal/resources/contenttype/test_resources/create.tf index bb9778d..60d27a2 100644 --- a/internal/resources/contenttype/test_resources/create.tf +++ b/internal/resources/contenttype/test_resources/create.tf @@ -1,5 +1,6 @@ resource "contentful_contenttype" "{{ .identifier }}" { space_id = "{{ .spaceId }}" + environment = "master" {{.id_definition}} name = "tf_test1" description = "{{.desc}}" diff --git a/internal/resources/contenttype/test_resources/link_config.tf b/internal/resources/contenttype/test_resources/link_config.tf index add70eb..8212a92 100644 --- a/internal/resources/contenttype/test_resources/link_config.tf +++ b/internal/resources/contenttype/test_resources/link_config.tf @@ -1,5 +1,6 @@ resource "contentful_contenttype" "{{ .identifier }}" { space_id = "{{ .spaceId }}" + environment = "master" name = "tf_test1" description = "Terraform Acc Test Content Type description change" display_field = "field1" @@ -28,6 +29,7 @@ resource "contentful_contenttype" "{{ .identifier }}" { resource "contentful_contenttype" "{{ .linkIdentifier }}" { space_id = "{{ .spaceId }}" name = "tf_linked" + environment = "master" description = "Terraform Acc Test Content Type with links" display_field = "asset_field" fields =[{ diff --git a/internal/resources/contenttype/test_resources/update.tf b/internal/resources/contenttype/test_resources/update.tf index c6290df..2da5d2a 100644 --- a/internal/resources/contenttype/test_resources/update.tf +++ b/internal/resources/contenttype/test_resources/update.tf @@ -1,5 +1,6 @@ resource "contentful_contenttype" "{{ .identifier }}" { space_id = "{{ .spaceId }}" + environment = "master" name = "tf_test1" description = "Terraform Acc Test Content Type description change" display_field = "field1" diff --git a/internal/resources/contenttype/test_resources/update_duplicate_field.tf b/internal/resources/contenttype/test_resources/update_duplicate_field.tf new file mode 100644 index 0000000..4ea677b --- /dev/null +++ b/internal/resources/contenttype/test_resources/update_duplicate_field.tf @@ -0,0 +1,34 @@ +resource "contentful_contenttype" "{{ .identifier }}" { + space_id = "{{ .spaceId }}" + environment = "master" + name = "tf_test1" + description = "Terraform Acc Test Content Type description change" + display_field = "field1" + manage_field_controls = true + fields = [{ + id = "field1" + name = "Field 1 name change" + required = true + type = "Text" + }, + { + id = "field1" + name = "Field 1 name change" + required = true + type = "Text" + }, + { + id = "field3" + name = "Field 3 new field" + required = true + type = "Integer" + control = { + widget_id = "numberEditor" + widget_namespace = "builtin" + settings = { + help_text = "blabla" + bulk_editing = true + } + }, + }] +} \ No newline at end of file diff --git a/internal/utils/container.go b/internal/utils/container.go index 9525b3b..748b82b 100644 --- a/internal/utils/container.go +++ b/internal/utils/container.go @@ -2,11 +2,11 @@ package utils import ( "github.com/flaconi/contentful-go" - "github.com/flaconi/contentful-go/service/common" + "github.com/flaconi/contentful-go/service/cma" ) type ProviderData struct { Client *contentful.Client - CMAClient common.SpaceIdClientBuilder + CMAClient cma.SpaceIdClientBuilder OrganizationId string } diff --git a/internal/utils/hcl.go b/internal/utils/hcl.go index c29bc72..7d8b808 100644 --- a/internal/utils/hcl.go +++ b/internal/utils/hcl.go @@ -22,11 +22,5 @@ func HCLTemplateFromPath(path string, params map[string]any) string { panic(err) } - var out bytes.Buffer - tmpl := template.Must(template.New("hcl").Parse(string(data))) - err = tmpl.Execute(&out, params) - if err != nil { - panic(err) - } - return out.String() + return HCLTemplate(string(data), params) } From 749f0e6b1ede273cdc33aa4270eb22a33e654cce Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 11 Mar 2024 10:35:41 +0100 Subject: [PATCH 173/192] Release v3.0.0 (#29) Co-authored-by: Engerim --- .changes/unreleased/Added-20240306-110007.yaml | 3 --- .changes/unreleased/Added-20240306-110048.yaml | 3 --- .changes/unreleased/Changed-20240306-105943.yaml | 3 --- .changes/v3.0.0.md | 6 ++++++ CHANGELOG.md | 7 +++++++ 5 files changed, 13 insertions(+), 9 deletions(-) delete mode 100644 .changes/unreleased/Added-20240306-110007.yaml delete mode 100644 .changes/unreleased/Added-20240306-110048.yaml delete mode 100644 .changes/unreleased/Changed-20240306-105943.yaml create mode 100644 .changes/v3.0.0.md diff --git a/.changes/unreleased/Added-20240306-110007.yaml b/.changes/unreleased/Added-20240306-110007.yaml deleted file mode 100644 index 8594c0c..0000000 --- a/.changes/unreleased/Added-20240306-110007.yaml +++ /dev/null @@ -1,3 +0,0 @@ -kind: Added -body: added for content types unique validation -time: 2024-03-06T11:00:07.863547+01:00 diff --git a/.changes/unreleased/Added-20240306-110048.yaml b/.changes/unreleased/Added-20240306-110048.yaml deleted file mode 100644 index a3a09da..0000000 --- a/.changes/unreleased/Added-20240306-110048.yaml +++ /dev/null @@ -1,3 +0,0 @@ -kind: Added -body: switch to latest version of the contentful go lib -time: 2024-03-06T11:00:48.116188+01:00 diff --git a/.changes/unreleased/Changed-20240306-105943.yaml b/.changes/unreleased/Changed-20240306-105943.yaml deleted file mode 100644 index 577ea9c..0000000 --- a/.changes/unreleased/Changed-20240306-105943.yaml +++ /dev/null @@ -1,3 +0,0 @@ -kind: Changed -body: environment for content type is now required -time: 2024-03-06T10:59:43.318104+01:00 diff --git a/.changes/v3.0.0.md b/.changes/v3.0.0.md new file mode 100644 index 0000000..3dcfd3e --- /dev/null +++ b/.changes/v3.0.0.md @@ -0,0 +1,6 @@ +## v3.0.0 - 2024-03-11 +### Added +* added for content types unique validation +* switch to latest version of the contentful go lib +### Changed +* environment for content type is now required diff --git a/CHANGELOG.md b/CHANGELOG.md index b88dfb6..bcae474 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,13 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), and is generated by [Changie](https://github.com/miniscruff/changie). +## v3.0.0 - 2024-03-11 +### Added +* added for content types unique validation +* switch to latest version of the contentful go lib +### Changed +* environment for content type is now required + ## v2.0.0 - 2023-12-19 ### Added * Add support for preview api keys From a0db2e450e4b19db56558c2dbac6899c328bd767 Mon Sep 17 00:00:00 2001 From: Thomas De Meyer Date: Fri, 19 Apr 2024 09:59:54 +0200 Subject: [PATCH 174/192] fix: fixed incorrect documentation --- .changes/unreleased/Fixed-20240419-095936.yaml | 3 +++ examples/resources/contentful_asset/resource.tf | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 .changes/unreleased/Fixed-20240419-095936.yaml diff --git a/.changes/unreleased/Fixed-20240419-095936.yaml b/.changes/unreleased/Fixed-20240419-095936.yaml new file mode 100644 index 0000000..c260eba --- /dev/null +++ b/.changes/unreleased/Fixed-20240419-095936.yaml @@ -0,0 +1,3 @@ +kind: Fixed +body: Fixed documentation +time: 2024-04-19T09:59:36.084984322+02:00 diff --git a/examples/resources/contentful_asset/resource.tf b/examples/resources/contentful_asset/resource.tf index f7466aa..7f2b2a2 100644 --- a/examples/resources/contentful_asset/resource.tf +++ b/examples/resources/contentful_asset/resource.tf @@ -12,7 +12,7 @@ resource "contentful_asset" "example_asset" { locale = "en-US" content = "asset description" } - file = { + file { upload = "https://images.ctfassets.net/fo9twyrwpveg/2VQx7vz73aMEYi20MMgCk0/66e502115b1f1f973a944b4bd2cc536f/IC-1H_Modern_Stack_Website.svg" fileName = "example.jpeg" contentType = "image/jpeg" @@ -20,4 +20,4 @@ resource "contentful_asset" "example_asset" { } published = false archived = false -} \ No newline at end of file +} From cbcc5f43648e4e019bd620c10f6c85b93199e827 Mon Sep 17 00:00:00 2001 From: Thomas De Meyer Date: Fri, 19 Apr 2024 12:22:08 +0200 Subject: [PATCH 175/192] feat: added option to set different base url --- .../unreleased/Added-20240419-122122.yaml | 3 + .../unreleased/Security-20240419-122147.yaml | 3 + Makefile | 25 -- Taskfile.yml | 32 +++ contentful/provider.go | 20 +- contentful/resource_contentful_apikey.go | 4 +- contentful/resource_contentful_asset.go | 11 +- contentful/resource_contentful_contenttype.go | 4 +- contentful/resource_contentful_entry.go | 4 +- contentful/resource_contentful_environment.go | 11 +- contentful/resource_contentful_locale.go | 4 +- contentful/resource_contentful_space.go | 4 +- contentful/resource_contentful_webhook.go | 4 +- docs/index.md | 12 + docs/resources/apikey.md | 4 +- docs/resources/asset.md | 6 +- docs/resources/contenttype.md | 4 +- docs/resources/entry.md | 4 +- docs/resources/environment.md | 4 +- docs/resources/locale.md | 4 +- docs/resources/space.md | 4 +- docs/resources/webhook.md | 4 +- examples/provider/provider.tf | 4 + go.mod | 77 ++++--- go.sum | 216 +++++++++--------- main.go | 14 +- 26 files changed, 279 insertions(+), 207 deletions(-) create mode 100644 .changes/unreleased/Added-20240419-122122.yaml create mode 100644 .changes/unreleased/Security-20240419-122147.yaml delete mode 100644 Makefile create mode 100644 Taskfile.yml create mode 100644 examples/provider/provider.tf diff --git a/.changes/unreleased/Added-20240419-122122.yaml b/.changes/unreleased/Added-20240419-122122.yaml new file mode 100644 index 0000000..1128b1c --- /dev/null +++ b/.changes/unreleased/Added-20240419-122122.yaml @@ -0,0 +1,3 @@ +kind: Added +body: Added option to set different base url for API +time: 2024-04-19T12:21:22.905074424+02:00 diff --git a/.changes/unreleased/Security-20240419-122147.yaml b/.changes/unreleased/Security-20240419-122147.yaml new file mode 100644 index 0000000..2bc0f6b --- /dev/null +++ b/.changes/unreleased/Security-20240419-122147.yaml @@ -0,0 +1,3 @@ +kind: Security +body: Updated dependencies +time: 2024-04-19T12:21:47.592833186+02:00 diff --git a/Makefile b/Makefile deleted file mode 100644 index 46a67b4..0000000 --- a/Makefile +++ /dev/null @@ -1,25 +0,0 @@ -.PHONY: build, test-unit, interactive, testacc - -build: - go build - -test-unit: build - sudo docker run \ - -e CONTENTFUL_MANAGEMENT_TOKEN=${CONTENTFUL_MANAGEMENT_TOKEN} \ - -e CONTENTFUL_ORGANIZATION_ID=${CONTENTFUL_ORGANIZATION_ID} \ - -e SPACE_ID=${SPACE_ID} \ - -e "TF_ACC=true" \ - terraform-provider-contentful \ - go test ./... -v - -interactive: - sudo -S docker run -it \ - -v $(shell pwd):/go/src/github.com/labd/terraform-provider-contentful \ - -e CONTENTFUL_MANAGEMENT_TOKEN=${CONTENTFUL_MANAGEMENT_TOKEN} \ - -e CONTENTFUL_ORGANIZATION_ID=${CONTENTFUL_ORGANIZATION_ID} \ - -e SPACE_ID=${SPACE_ID} \ - terraform-provider-contentful \ - bash - -testacc: - TF_ACC=1 go test -v ./... diff --git a/Taskfile.yml b/Taskfile.yml new file mode 100644 index 0000000..5b36a74 --- /dev/null +++ b/Taskfile.yml @@ -0,0 +1,32 @@ +version: '3' + +tasks: + format: + cmds: + - go fmt ./... + + test: + cmds: + - go test -v ./... + + generate: + cmds: + - go generate ./... + + coverage-html: + cmds: + - go test -race -coverprofile=coverage.txt -covermode=atomic -coverpkg=./... ./... + - go tool cover -html=coverage.txt + + coverage: + cmds: + - go test -race -coverprofile=coverage.txt -covermode=atomic -coverpkg=./... ./... + - go tool cover -func=coverage.txt + + testacc: + cmds: + - TF_ACC=1 go test -v ./... + + testacct: + cmds: + - TF_ACC=1 go test -race -coverprofile=coverage.txt -covermode=atomic -coverpkg=./... -v ./... diff --git a/contentful/provider.go b/contentful/provider.go index 0077450..8e36f63 100644 --- a/contentful/provider.go +++ b/contentful/provider.go @@ -1,6 +1,8 @@ package contentful import ( + "context" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" contentful "github.com/labd/contentful-go" ) @@ -21,6 +23,18 @@ func Provider() *schema.Provider { DefaultFunc: schema.EnvDefaultFunc("CONTENTFUL_ORGANIZATION_ID", nil), Description: "The organization ID", }, + "base_url": { + Type: schema.TypeString, + Optional: true, + DefaultFunc: schema.EnvDefaultFunc("CONTENTFUL_BASE_URL", "https://api.contentful.com"), + Description: "The base url to use for the Contentful API. Defaults to https://api.contentful.com", + }, + "environment": { + Type: schema.TypeString, + Optional: true, + DefaultFunc: schema.EnvDefaultFunc("CONTENTFUL_ENVIRONMENT", "master"), + Description: "The environment to use for the Contentful API. Defaults to master", + }, }, ResourcesMap: map[string]*schema.Resource{ "contentful_space": resourceContentfulSpace(), @@ -32,14 +46,16 @@ func Provider() *schema.Provider { "contentful_entry": resourceContentfulEntry(), "contentful_asset": resourceContentfulAsset(), }, - ConfigureFunc: providerConfigure, + ConfigureContextFunc: providerConfigure, } } // providerConfigure sets the configuration for the Terraform Provider -func providerConfigure(d *schema.ResourceData) (interface{}, error) { +func providerConfigure(_ context.Context, d *schema.ResourceData) (interface{}, diag.Diagnostics) { cma := contentful.NewCMA(d.Get("cma_token").(string)) cma.SetOrganization(d.Get("organization_id").(string)) + cma.BaseURL = d.Get("base_url").(string) + cma.SetEnvironment(d.Get("environment").(string)) if logBoolean != "" { cma.Debug = true diff --git a/contentful/resource_contentful_apikey.go b/contentful/resource_contentful_apikey.go index dbf758d..1a9eda5 100644 --- a/contentful/resource_contentful_apikey.go +++ b/contentful/resource_contentful_apikey.go @@ -2,11 +2,13 @@ package contentful import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - contentful "github.com/labd/contentful-go" + "github.com/labd/contentful-go" ) func resourceContentfulAPIKey() *schema.Resource { return &schema.Resource{ + Description: "A Contentful API Key represents a token that can be used to authenticate against the Contentful Content Delivery API and Content Preview API.", + Create: resourceCreateAPIKey, Read: resourceReadAPIKey, Update: resourceUpdateAPIKey, diff --git a/contentful/resource_contentful_asset.go b/contentful/resource_contentful_asset.go index b7b6a22..f3e3617 100644 --- a/contentful/resource_contentful_asset.go +++ b/contentful/resource_contentful_asset.go @@ -5,15 +5,16 @@ import ( "time" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - contentful "github.com/labd/contentful-go" + "github.com/labd/contentful-go" ) func resourceContentfulAsset() *schema.Resource { return &schema.Resource{ - Create: resourceCreateAsset, - Read: resourceReadAsset, - Update: resourceUpdateAsset, - Delete: resourceDeleteAsset, + Description: "A Contentful Asset represents a file that can be used in entries.", + Create: resourceCreateAsset, + Read: resourceReadAsset, + Update: resourceUpdateAsset, + Delete: resourceDeleteAsset, Schema: map[string]*schema.Schema{ "asset_id": { diff --git a/contentful/resource_contentful_contenttype.go b/contentful/resource_contentful_contenttype.go index a687e7e..0051a0a 100644 --- a/contentful/resource_contentful_contenttype.go +++ b/contentful/resource_contentful_contenttype.go @@ -2,11 +2,13 @@ package contentful import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - contentful "github.com/labd/contentful-go" + "github.com/labd/contentful-go" ) func resourceContentfulContentType() *schema.Resource { return &schema.Resource{ + Description: "A Contentful Content Type represents a structure for entries.", + Create: resourceContentTypeCreate, Read: resourceContentTypeRead, Update: resourceContentTypeUpdate, diff --git a/contentful/resource_contentful_entry.go b/contentful/resource_contentful_entry.go index f8d3431..f302f9e 100644 --- a/contentful/resource_contentful_entry.go +++ b/contentful/resource_contentful_entry.go @@ -2,11 +2,13 @@ package contentful import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - contentful "github.com/labd/contentful-go" + "github.com/labd/contentful-go" ) func resourceContentfulEntry() *schema.Resource { return &schema.Resource{ + Description: "A Contentful Entry represents a piece of content in a space.", + Create: resourceCreateEntry, Read: resourceReadEntry, Update: resourceUpdateEntry, diff --git a/contentful/resource_contentful_environment.go b/contentful/resource_contentful_environment.go index 4f4b254..097cc5e 100644 --- a/contentful/resource_contentful_environment.go +++ b/contentful/resource_contentful_environment.go @@ -2,15 +2,16 @@ package contentful import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - contentful "github.com/labd/contentful-go" + "github.com/labd/contentful-go" ) func resourceContentfulEnvironment() *schema.Resource { return &schema.Resource{ - Create: resourceCreateEnvironment, - Read: resourceReadEnvironment, - Update: resourceUpdateEnvironment, - Delete: resourceDeleteEnvironment, + Description: "A Contentful Environment represents a space environment.", + Create: resourceCreateEnvironment, + Read: resourceReadEnvironment, + Update: resourceUpdateEnvironment, + Delete: resourceDeleteEnvironment, Schema: map[string]*schema.Schema{ "version": { diff --git a/contentful/resource_contentful_locale.go b/contentful/resource_contentful_locale.go index f31e9c7..755bc46 100644 --- a/contentful/resource_contentful_locale.go +++ b/contentful/resource_contentful_locale.go @@ -2,11 +2,13 @@ package contentful import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - contentful "github.com/labd/contentful-go" + "github.com/labd/contentful-go" ) func resourceContentfulLocale() *schema.Resource { return &schema.Resource{ + Description: "A Contentful Locale represents a language and region combination.", + Create: resourceCreateLocale, Read: resourceReadLocale, Update: resourceUpdateLocale, diff --git a/contentful/resource_contentful_space.go b/contentful/resource_contentful_space.go index adfae00..36bc188 100644 --- a/contentful/resource_contentful_space.go +++ b/contentful/resource_contentful_space.go @@ -2,11 +2,13 @@ package contentful import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - contentful "github.com/labd/contentful-go" + "github.com/labd/contentful-go" ) func resourceContentfulSpace() *schema.Resource { return &schema.Resource{ + Description: "A Contentful Space represents a space in Contentful.", + Create: resourceSpaceCreate, Read: resourceSpaceRead, Update: resourceSpaceUpdate, diff --git a/contentful/resource_contentful_webhook.go b/contentful/resource_contentful_webhook.go index 6119e9d..e74b749 100644 --- a/contentful/resource_contentful_webhook.go +++ b/contentful/resource_contentful_webhook.go @@ -2,11 +2,13 @@ package contentful import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - contentful "github.com/labd/contentful-go" + "github.com/labd/contentful-go" ) func resourceContentfulWebhook() *schema.Resource { return &schema.Resource{ + Description: "A Contentful Webhook represents a webhook that can be used to notify external services of changes in a space.", + Create: resourceCreateWebhook, Read: resourceReadWebhook, Update: resourceUpdateWebhook, diff --git a/docs/index.md b/docs/index.md index 85f8c5e..eb0e03b 100644 --- a/docs/index.md +++ b/docs/index.md @@ -10,7 +10,14 @@ description: |- +## Example Usage +```terraform +provider "contentful" { + cma_token = "" + organization_id = "" +} +``` ## Schema @@ -19,3 +26,8 @@ description: |- - `cma_token` (String) The Contentful Management API token - `organization_id` (String) The organization ID + +### Optional + +- `base_url` (String) The base url to use for the Contentful API. Defaults to https://api.contentful.com +- `environment` (String) The environment to use for the Contentful API. Defaults to master diff --git a/docs/resources/apikey.md b/docs/resources/apikey.md index f847af3..fa8e221 100644 --- a/docs/resources/apikey.md +++ b/docs/resources/apikey.md @@ -3,12 +3,12 @@ page_title: "contentful_apikey Resource - terraform-provider-contentful" subcategory: "" description: |- - + A Contentful API Key represents a token that can be used to authenticate against the Contentful Content Delivery API and Content Preview API. --- # contentful_apikey (Resource) - +A Contentful API Key represents a token that can be used to authenticate against the Contentful Content Delivery API and Content Preview API. ## Example Usage diff --git a/docs/resources/asset.md b/docs/resources/asset.md index ebf3b77..cec37a6 100644 --- a/docs/resources/asset.md +++ b/docs/resources/asset.md @@ -3,12 +3,12 @@ page_title: "contentful_asset Resource - terraform-provider-contentful" subcategory: "" description: |- - + A Contentful Asset represents a file that can be used in entries. --- # contentful_asset (Resource) - +A Contentful Asset represents a file that can be used in entries. ## Example Usage @@ -27,7 +27,7 @@ resource "contentful_asset" "example_asset" { locale = "en-US" content = "asset description" } - file = { + file { upload = "https://images.ctfassets.net/fo9twyrwpveg/2VQx7vz73aMEYi20MMgCk0/66e502115b1f1f973a944b4bd2cc536f/IC-1H_Modern_Stack_Website.svg" fileName = "example.jpeg" contentType = "image/jpeg" diff --git a/docs/resources/contenttype.md b/docs/resources/contenttype.md index 73317da..7252736 100644 --- a/docs/resources/contenttype.md +++ b/docs/resources/contenttype.md @@ -3,12 +3,12 @@ page_title: "contentful_contenttype Resource - terraform-provider-contentful" subcategory: "" description: |- - + A Contentful Content Type represents a structure for entries. --- # contentful_contenttype (Resource) - +A Contentful Content Type represents a structure for entries. ## Example Usage diff --git a/docs/resources/entry.md b/docs/resources/entry.md index ba7b808..61233ec 100644 --- a/docs/resources/entry.md +++ b/docs/resources/entry.md @@ -3,12 +3,12 @@ page_title: "contentful_entry Resource - terraform-provider-contentful" subcategory: "" description: |- - + A Contentful Entry represents a piece of content in a space. --- # contentful_entry (Resource) - +A Contentful Entry represents a piece of content in a space. ## Example Usage diff --git a/docs/resources/environment.md b/docs/resources/environment.md index 465439a..b863063 100644 --- a/docs/resources/environment.md +++ b/docs/resources/environment.md @@ -3,12 +3,12 @@ page_title: "contentful_environment Resource - terraform-provider-contentful" subcategory: "" description: |- - + A Contentful Environment represents a space environment. --- # contentful_environment (Resource) - +A Contentful Environment represents a space environment. ## Example Usage diff --git a/docs/resources/locale.md b/docs/resources/locale.md index f27d118..905e44b 100644 --- a/docs/resources/locale.md +++ b/docs/resources/locale.md @@ -3,12 +3,12 @@ page_title: "contentful_locale Resource - terraform-provider-contentful" subcategory: "" description: |- - + A Contentful Locale represents a language and region combination. --- # contentful_locale (Resource) - +A Contentful Locale represents a language and region combination. ## Example Usage diff --git a/docs/resources/space.md b/docs/resources/space.md index 75eca53..95f4139 100644 --- a/docs/resources/space.md +++ b/docs/resources/space.md @@ -3,12 +3,12 @@ page_title: "contentful_space Resource - terraform-provider-contentful" subcategory: "" description: |- - + A Contentful Space represents a space in Contentful. --- # contentful_space (Resource) - +A Contentful Space represents a space in Contentful. ## Example Usage diff --git a/docs/resources/webhook.md b/docs/resources/webhook.md index d982e4b..5036223 100644 --- a/docs/resources/webhook.md +++ b/docs/resources/webhook.md @@ -3,12 +3,12 @@ page_title: "contentful_webhook Resource - terraform-provider-contentful" subcategory: "" description: |- - + A Contentful Webhook represents a webhook that can be used to notify external services of changes in a space. --- # contentful_webhook (Resource) - +A Contentful Webhook represents a webhook that can be used to notify external services of changes in a space. ## Example Usage diff --git a/examples/provider/provider.tf b/examples/provider/provider.tf new file mode 100644 index 0000000..87a6940 --- /dev/null +++ b/examples/provider/provider.tf @@ -0,0 +1,4 @@ +provider "contentful" { + cma_token = "" + organization_id = "" +} diff --git a/go.mod b/go.mod index 105f009..dbdc91a 100644 --- a/go.mod +++ b/go.mod @@ -2,61 +2,74 @@ module github.com/labd/terraform-provider-contentful go 1.21 +//replace github.com/labd/contentful-go => ../contentful-go + require ( - github.com/hashicorp/terraform-plugin-docs v0.16.0 + github.com/hashicorp/terraform-plugin-docs v0.19.0 github.com/labd/contentful-go v0.5.3 ) require ( + github.com/BurntSushi/toml v1.3.2 // indirect + github.com/Kunde21/markdownfmt/v3 v3.1.0 // indirect github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/semver/v3 v3.2.1 // indirect github.com/Masterminds/sprig/v3 v3.2.3 // indirect - github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 // indirect + github.com/ProtonMail/go-crypto v1.1.0-alpha.2-proton // indirect github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect github.com/armon/go-radix v1.0.0 // indirect github.com/bgentry/speakeasy v0.1.0 // indirect - github.com/cloudflare/circl v1.3.3 // indirect - github.com/google/uuid v1.3.1 // indirect - github.com/hashicorp/hc-install v0.6.0 // indirect + github.com/bmatcuk/doublestar/v4 v4.6.1 // indirect + github.com/cloudflare/circl v1.3.7 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/hashicorp/cli v1.1.6 // indirect + github.com/hashicorp/hc-install v0.6.4 // indirect github.com/hashicorp/terraform-plugin-log v0.9.0 // indirect - github.com/hashicorp/terraform-registry-address v0.2.2 // indirect + github.com/hashicorp/terraform-registry-address v0.2.3 // indirect github.com/hashicorp/terraform-svchost v0.1.1 // indirect github.com/huandu/xstrings v1.4.0 // indirect github.com/imdario/mergo v0.3.16 // indirect - github.com/mitchellh/cli v1.1.5 // indirect + github.com/mattn/go-runewidth v0.0.15 // indirect github.com/posener/complete v1.2.3 // indirect - github.com/russross/blackfriday v1.6.0 // indirect - github.com/shopspring/decimal v1.3.1 // indirect - github.com/spf13/cast v1.5.1 // indirect - github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect + github.com/rivo/uniseg v0.4.7 // indirect + github.com/shopspring/decimal v1.4.0 // indirect + github.com/spf13/cast v1.6.0 // indirect + github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect - golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20230913181813-007df8e322eb // indirect + github.com/yuin/goldmark v1.7.1 // indirect + github.com/yuin/goldmark-meta v1.1.0 // indirect + go.abhg.dev/goldmark/frontmatter v0.2.0 // indirect + golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f // indirect + golang.org/x/sync v0.7.0 // indirect + golang.org/x/tools v0.20.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240415180920-8c6c420018be // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) require ( github.com/agext/levenshtein v1.2.3 // indirect - github.com/fatih/color v1.15.0 // indirect - github.com/golang/protobuf v1.5.3 // indirect - github.com/google/go-cmp v0.5.9 // indirect + github.com/fatih/color v1.16.0 // indirect + github.com/golang/protobuf v1.5.4 // indirect + github.com/google/go-cmp v0.6.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-checkpoint v0.5.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 // indirect - github.com/hashicorp/go-hclog v1.5.0 // indirect + github.com/hashicorp/go-hclog v1.6.3 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect - github.com/hashicorp/go-plugin v1.5.1 // indirect + github.com/hashicorp/go-plugin v1.6.0 // indirect github.com/hashicorp/go-uuid v1.0.3 // indirect github.com/hashicorp/go-version v1.6.0 // indirect - github.com/hashicorp/hcl/v2 v2.18.0 // indirect + github.com/hashicorp/hcl/v2 v2.20.1 // indirect github.com/hashicorp/logutils v1.0.0 // indirect - github.com/hashicorp/terraform-exec v0.19.0 // indirect - github.com/hashicorp/terraform-json v0.17.1 // indirect - github.com/hashicorp/terraform-plugin-go v0.19.0 // indirect - github.com/hashicorp/terraform-plugin-sdk/v2 v2.29.0 + github.com/hashicorp/terraform-exec v0.20.0 // indirect + github.com/hashicorp/terraform-json v0.21.0 // indirect + github.com/hashicorp/terraform-plugin-go v0.22.2 // indirect + github.com/hashicorp/terraform-plugin-sdk/v2 v2.33.0 github.com/hashicorp/yamux v0.1.1 // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.19 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/go-testing-interface v1.14.1 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect @@ -64,14 +77,14 @@ require ( github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/oklog/run v1.1.0 // indirect github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect - github.com/zclconf/go-cty v1.14.0 // indirect - golang.org/x/crypto v0.13.0 // indirect - golang.org/x/mod v0.12.0 // indirect - golang.org/x/net v0.15.0 // indirect - golang.org/x/sys v0.12.0 // indirect - golang.org/x/text v0.13.0 // indirect + github.com/zclconf/go-cty v1.14.4 // indirect + golang.org/x/crypto v0.22.0 // indirect + golang.org/x/mod v0.17.0 // indirect + golang.org/x/net v0.24.0 // indirect + golang.org/x/sys v0.19.0 // indirect + golang.org/x/text v0.14.0 // indirect google.golang.org/appengine v1.6.8 // indirect - google.golang.org/grpc v1.58.1 // indirect - google.golang.org/protobuf v1.31.0 // indirect + google.golang.org/grpc v1.63.2 // indirect + google.golang.org/protobuf v1.33.0 // indirect moul.io/http2curl v1.0.1-0.20190925090545-5cd742060b0e // indirect ) diff --git a/go.sum b/go.sum index b675fca..8c2a1be 100644 --- a/go.sum +++ b/go.sum @@ -1,52 +1,53 @@ dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= +github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/Kunde21/markdownfmt/v3 v3.1.0 h1:KiZu9LKs+wFFBQKhrZJrFZwtLnCCWJahL+S+E/3VnM0= +github.com/Kunde21/markdownfmt/v3 v3.1.0/go.mod h1:tPXN1RTyOzJwhfHoon9wUr4HGYmWgVxSQN6VBJDkrVc= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= -github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= -github.com/Masterminds/sprig/v3 v3.2.1/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk= github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA= github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= -github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 h1:kkhsdkhsCvIsutKu5zLMgWtgh9YxGCNAw8Ad8hjwfYg= -github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= -github.com/acomagu/bufpipe v1.0.4 h1:e3H4WUzM3npvo5uv95QuJM3cQspFNtFBzvJ2oNjKIDQ= -github.com/acomagu/bufpipe v1.0.4/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4= +github.com/ProtonMail/go-crypto v1.1.0-alpha.2-proton h1:HKz85FwoXx86kVtTvFke7rgHvq/HoloSUvW5semjFWs= +github.com/ProtonMail/go-crypto v1.1.0-alpha.2-proton/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec= github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY= github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4= -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/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bmatcuk/doublestar/v4 v4.6.1 h1:FH9SifrbvJhnlQpztAx++wlkk70QBf0iBWDwNy7PA4I= +github.com/bmatcuk/doublestar/v4 v4.6.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA= github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8= -github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= -github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs= -github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= +github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= +github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= +github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= +github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= 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/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= -github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= -github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= -github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= -github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= -github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= +github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= +github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= -github.com/go-git/go-billy/v5 v5.4.1 h1:Uwp5tDRkPr+l/TnbHOQzp+tmJfLceOlbVucgpTz8ix4= -github.com/go-git/go-billy/v5 v5.4.1/go.mod h1:vjbugF6Fz7JIflbVpl1hJsGjSHNltrSw45YK/ukIvQg= -github.com/go-git/go-git/v5 v5.8.1 h1:Zo79E4p7TRk0xoRgMq0RShiTHGKcKI4+DI6BfJc/Q+A= -github.com/go-git/go-git/v5 v5.8.1/go.mod h1:FHFuoD6yGz5OSKEBK+aWN9Oah0q54Jxl0abmj6GnqAo= +github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU= +github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow= +github.com/go-git/go-git/v5 v5.12.0 h1:7Md+ndsjrzZxbddRDZjF14qK+NN56sy6wkqaVrjZtys= +github.com/go-git/go-git/v5 v5.12.0/go.mod h1:FTM9VKtnI2m65hNI/TenDDDnUf2Q9FHnXYjuz9i5OEY= 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/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= @@ -54,16 +55,17 @@ github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4er github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= -github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/hashicorp/cli v1.1.6 h1:CMOV+/LJfL1tXCOKrgAX0uRKnzjj/mpmqNXloRSy2K8= +github.com/hashicorp/cli v1.1.6/go.mod h1:MPon5QYlgjjo0BSoAiN0ESeT5fRzDjVRp+uioJ0piz4= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -74,44 +76,42 @@ github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9n github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 h1:1/D3zfFHttUKaCaGKZ/dR2roBXv0vKbSCnssIldfQdI= github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320/go.mod h1:EiZBMaudVLy8fmjf9Npq1dq9RalhveqZG5w/yz3mHWs= -github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c= -github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= +github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/go-plugin v1.5.1 h1:oGm7cWBaYIp3lJpx1RUEfLWophprE2EV/KUeqBYo+6k= -github.com/hashicorp/go-plugin v1.5.1/go.mod h1:w1sAEES3g3PuV/RzUrgow20W2uErMly84hhD3um1WL4= +github.com/hashicorp/go-plugin v1.6.0 h1:wgd4KxHJTVGGqWBq4QPB1i5BZNEx9BR8+OFmHDmTk8A= +github.com/hashicorp/go-plugin v1.6.0/go.mod h1:lBS5MtSSBZk0SHc66KACcjjlU6WzEVP/8pwz68aMkCI= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/hc-install v0.6.0 h1:fDHnU7JNFNSQebVKYhHZ0va1bC6SrPQ8fpebsvNr2w4= -github.com/hashicorp/hc-install v0.6.0/go.mod h1:10I912u3nntx9Umo1VAeYPUUuehk0aRQJYpMwbX5wQA= -github.com/hashicorp/hcl/v2 v2.18.0 h1:wYnG7Lt31t2zYkcquwgKo6MWXzRUDIeIVU5naZwHLl8= -github.com/hashicorp/hcl/v2 v2.18.0/go.mod h1:ThLC89FV4p9MPW804KVbe/cEXoQ8NZEh+JtMeeGErHE= +github.com/hashicorp/hc-install v0.6.4 h1:QLqlM56/+SIIGvGcfFiwMY3z5WGXT066suo/v9Km8e0= +github.com/hashicorp/hc-install v0.6.4/go.mod h1:05LWLy8TD842OtgcfBbOT0WMoInBMUSHjmDx10zuBIA= +github.com/hashicorp/hcl/v2 v2.20.1 h1:M6hgdyz7HYt1UN9e61j+qKJBqR3orTWbI1HKBJEdxtc= +github.com/hashicorp/hcl/v2 v2.20.1/go.mod h1:TZDqQ4kNKCbh1iJp99FdPiUaVDDUPivbqxZulxDYqL4= 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/terraform-exec v0.19.0 h1:FpqZ6n50Tk95mItTSS9BjeOVUb4eg81SpgVtZNNtFSM= -github.com/hashicorp/terraform-exec v0.19.0/go.mod h1:tbxUpe3JKruE9Cuf65mycSIT8KiNPZ0FkuTE3H4urQg= -github.com/hashicorp/terraform-json v0.17.1 h1:eMfvh/uWggKmY7Pmb3T85u86E2EQg6EQHgyRwf3RkyA= -github.com/hashicorp/terraform-json v0.17.1/go.mod h1:Huy6zt6euxaY9knPAFKjUITn8QxUFIe9VuSzb4zn/0o= -github.com/hashicorp/terraform-plugin-docs v0.16.0 h1:UmxFr3AScl6Wged84jndJIfFccGyBZn52KtMNsS12dI= -github.com/hashicorp/terraform-plugin-docs v0.16.0/go.mod h1:M3ZrlKBJAbPMtNOPwHicGi1c+hZUh7/g0ifT/z7TVfA= -github.com/hashicorp/terraform-plugin-go v0.19.0 h1:BuZx/6Cp+lkmiG0cOBk6Zps0Cb2tmqQpDM3iAtnhDQU= -github.com/hashicorp/terraform-plugin-go v0.19.0/go.mod h1:EhRSkEPNoylLQntYsk5KrDHTZJh9HQoumZXbOGOXmec= +github.com/hashicorp/terraform-exec v0.20.0 h1:DIZnPsqzPGuUnq6cH8jWcPunBfY+C+M8JyYF3vpnuEo= +github.com/hashicorp/terraform-exec v0.20.0/go.mod h1:ckKGkJWbsNqFKV1itgMnE0hY9IYf1HoiekpuN0eWoDw= +github.com/hashicorp/terraform-json v0.21.0 h1:9NQxbLNqPbEMze+S6+YluEdXgJmhQykRyRNd+zTI05U= +github.com/hashicorp/terraform-json v0.21.0/go.mod h1:qdeBs11ovMzo5puhrRibdD6d2Dq6TyE/28JiU4tIQxk= +github.com/hashicorp/terraform-plugin-docs v0.19.0 h1:ufXLte5Kx20LazYmGN2UZG2bN4aF0PmlDyuS1iKWSXo= +github.com/hashicorp/terraform-plugin-docs v0.19.0/go.mod h1:NPfKCSfzTtq+YCFHr2qTAMknWUxR8C4KgTbGkHULSV8= +github.com/hashicorp/terraform-plugin-go v0.22.2 h1:5o8uveu6eZUf5J7xGPV0eY0TPXg3qpmwX9sce03Bxnc= +github.com/hashicorp/terraform-plugin-go v0.22.2/go.mod h1:drq8Snexp9HsbFZddvyLHN6LuWHHndSQg+gV+FPkcIM= github.com/hashicorp/terraform-plugin-log v0.9.0 h1:i7hOA+vdAItN1/7UrfBqBwvYPQ9TFvymaRGZED3FCV0= github.com/hashicorp/terraform-plugin-log v0.9.0/go.mod h1:rKL8egZQ/eXSyDqzLUuwUYLVdlYeamldAHSxjUFADow= -github.com/hashicorp/terraform-plugin-sdk/v2 v2.29.0 h1:wcOKYwPI9IorAJEBLzgclh3xVolO7ZorYd6U1vnok14= -github.com/hashicorp/terraform-plugin-sdk/v2 v2.29.0/go.mod h1:qH/34G25Ugdj5FcM95cSoXzUgIbgfhVLXCcEcYaMwq8= -github.com/hashicorp/terraform-registry-address v0.2.2 h1:lPQBg403El8PPicg/qONZJDC6YlgCVbWDtNmmZKtBno= -github.com/hashicorp/terraform-registry-address v0.2.2/go.mod h1:LtwNbCihUoUZ3RYriyS2wF/lGPB6gF9ICLRtuDk7hSo= +github.com/hashicorp/terraform-plugin-sdk/v2 v2.33.0 h1:qHprzXy/As0rxedphECBEQAh3R4yp6pKksKHcqZx5G8= +github.com/hashicorp/terraform-plugin-sdk/v2 v2.33.0/go.mod h1:H+8tjs9TjV2w57QFVSMBQacf8k/E1XwLXGCARgViC6A= +github.com/hashicorp/terraform-registry-address v0.2.3 h1:2TAiKJ1A3MAkZlH1YI/aTVcLZRu7JseiXNRHbOAyoTI= +github.com/hashicorp/terraform-registry-address v0.2.3/go.mod h1:lFHA76T8jfQteVfT7caREqguFrW3c4MFSPhZB7HHgUM= github.com/hashicorp/terraform-svchost v0.1.1 h1:EZZimZ1GxdqFRinZ1tpJwVxxt49xc/S52uzrw4x0jKQ= github.com/hashicorp/terraform-svchost v0.1.1/go.mod h1:mNsjQfZyf/Jhz35v6/0LWcv26+X7JPS+buii2c9/ctc= github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE= github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= -github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= -github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU= github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= @@ -131,23 +131,19 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -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/labd/contentful-go v0.5.3 h1:dIT2OURBgV9Zf1zOAmXL4w+V9vDMNEpwBIPVTfXRzmE= github.com/labd/contentful-go v0.5.3/go.mod h1:fJnX/J/wrmFzSdPIrOs7ZfCaHsHz0LPWGA9RGpiRHB0= -github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= -github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mitchellh/cli v1.1.5 h1:OxRIeJXpAMztws/XHlN2vu6imG5Dpq+j61AzAX5fLng= -github.com/mitchellh/cli v1.1.5/go.mod h1:v8+iFts2sPIKUV1ltktPXMCC8fumSKFItNcD2cLtRR4= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= +github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= @@ -166,73 +162,73 @@ github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI= 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.3 h1:NP0eAhjcjImqslEwo/1hq7gpajME0fTLTezBKDqfXqo= github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= -github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= -github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= -github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww= -github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY= -github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= -github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= +github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= +github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= -github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= -github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= -github.com/skeema/knownhosts v1.2.0 h1:h9r9cf0+u7wSE+M183ZtMGgOJKiL96brpaz5ekfJCpM= -github.com/skeema/knownhosts v1.2.0/go.mod h1:g4fPeYpque7P0xefxtGzV81ihjC8sX2IqpAoNkjxbMo= +github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= +github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME= +github.com/skeema/knownhosts v1.2.2 h1:Iug2P4fLmDw9f41PB6thxUkNUkJzB5i+1/exaj40L3A= +github.com/skeema/knownhosts v1.2.2/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA= -github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48= +github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= +github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI= github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= -github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU= -github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= +github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8= +github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok= github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/zclconf/go-cty v1.14.0 h1:/Xrd39K7DXbHzlisFP9c4pHao4yyf+/Ug9LEz+Y/yhc= -github.com/zclconf/go-cty v1.14.0/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= +github.com/yuin/goldmark v1.7.1 h1:3bajkSilaCbjdKVsKdZjZCLBNPL9pYzrCakKaf4U49U= +github.com/yuin/goldmark v1.7.1/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= +github.com/yuin/goldmark-meta v1.1.0 h1:pWw+JLHGZe8Rk0EGsMVssiNb/AaPMHfSRszZeUeiOUc= +github.com/yuin/goldmark-meta v1.1.0/go.mod h1:U4spWENafuA7Zyg+Lj5RqK/MF+ovMYtBvXi1lBb2VP0= +github.com/zclconf/go-cty v1.14.4 h1:uXXczd9QDGsgu0i/QFR/hzI5NYCHLf6NQw/atrbnhq8= +github.com/zclconf/go-cty v1.14.4/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= +github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b h1:FosyBZYxY34Wul7O/MSKey3txpPYyCqVO5ZyceuQJEI= +github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8= +go.abhg.dev/goldmark/frontmatter v0.2.0 h1:P8kPG0YkL12+aYk2yU3xHv4tcXzeVnN+gU0tJ5JnxRw= +go.abhg.dev/goldmark/frontmatter v0.2.0/go.mod h1:XqrEkZuM57djk7zrlRUB02x8I5J0px76YjkOzhB4YlU= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= -golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= -golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= -golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck= -golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= -golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= -golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= +golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= +golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= +golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f h1:99ci1mjWVBWwJiEKYY6jWa4d2nTQVIEhZIptnrVb1XY= +golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= -golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= -golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8= -golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= +golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= +golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -244,47 +240,40 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= -golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= +golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= -golang.org/x/term v0.12.0 h1:/ZfYdc3zq+q02Rv9vGqTeSItdzZTSNDmfTi0mBAuidU= -golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= +golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= +golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= -golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= +golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY= +golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230913181813-007df8e322eb h1:Isk1sSH7bovx8Rti2wZK0UZF6oraBDK74uoyLEEVFN0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230913181813-007df8e322eb/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= -google.golang.org/grpc v1.58.1 h1:OL+Vz23DTtrrldqHK49FUOPHyY75rvFqJfXC84NYW58= -google.golang.org/grpc v1.58.1/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240415180920-8c6c420018be h1:LG9vZxsWGOmUKieR8wPAUR3u3MpnYFQZROPIMaXh7/A= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240415180920-8c6c420018be/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= +google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM= +google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -292,7 +281,8 @@ gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= moul.io/http2curl v1.0.1-0.20190925090545-5cd742060b0e h1:C7q+e9M5nggAvWfVg9Nl66kebKeuJlP3FD58V4RR5wo= diff --git a/main.go b/main.go index c9e17ff..790e38f 100644 --- a/main.go +++ b/main.go @@ -1,6 +1,7 @@ package main import ( + "flag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/plugin" "github.com/labd/terraform-provider-contentful/contentful" @@ -18,9 +19,18 @@ import ( //go:generate go run github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs func main() { - plugin.Serve(&plugin.ServeOpts{ + var debug bool + + flag.BoolVar(&debug, "debug", false, "set to true to run the provider with support for debuggers like delve") + flag.Parse() + + opts := &plugin.ServeOpts{ + Debug: debug, + ProviderAddr: "registry.terraform.io/labd/contentful", ProviderFunc: func() *schema.Provider { return contentful.Provider() }, - }) + } + + plugin.Serve(opts) } From d8495a1666745024217d7cf803f2231772fd7b22 Mon Sep 17 00:00:00 2001 From: demeyerthom Date: Fri, 19 Apr 2024 10:29:14 +0000 Subject: [PATCH 176/192] Release v0.5.0 --- .changes/unreleased/Added-20240419-122122.yaml | 3 --- .changes/unreleased/Fixed-20240419-095936.yaml | 3 --- .changes/unreleased/Security-20240419-122147.yaml | 3 --- .changes/v0.5.0.md | 7 +++++++ CHANGELOG.md | 8 ++++++++ 5 files changed, 15 insertions(+), 9 deletions(-) delete mode 100644 .changes/unreleased/Added-20240419-122122.yaml delete mode 100644 .changes/unreleased/Fixed-20240419-095936.yaml delete mode 100644 .changes/unreleased/Security-20240419-122147.yaml create mode 100644 .changes/v0.5.0.md diff --git a/.changes/unreleased/Added-20240419-122122.yaml b/.changes/unreleased/Added-20240419-122122.yaml deleted file mode 100644 index 1128b1c..0000000 --- a/.changes/unreleased/Added-20240419-122122.yaml +++ /dev/null @@ -1,3 +0,0 @@ -kind: Added -body: Added option to set different base url for API -time: 2024-04-19T12:21:22.905074424+02:00 diff --git a/.changes/unreleased/Fixed-20240419-095936.yaml b/.changes/unreleased/Fixed-20240419-095936.yaml deleted file mode 100644 index c260eba..0000000 --- a/.changes/unreleased/Fixed-20240419-095936.yaml +++ /dev/null @@ -1,3 +0,0 @@ -kind: Fixed -body: Fixed documentation -time: 2024-04-19T09:59:36.084984322+02:00 diff --git a/.changes/unreleased/Security-20240419-122147.yaml b/.changes/unreleased/Security-20240419-122147.yaml deleted file mode 100644 index 2bc0f6b..0000000 --- a/.changes/unreleased/Security-20240419-122147.yaml +++ /dev/null @@ -1,3 +0,0 @@ -kind: Security -body: Updated dependencies -time: 2024-04-19T12:21:47.592833186+02:00 diff --git a/.changes/v0.5.0.md b/.changes/v0.5.0.md new file mode 100644 index 0000000..69be05f --- /dev/null +++ b/.changes/v0.5.0.md @@ -0,0 +1,7 @@ +## v0.5.0 - 2024-04-19 +### Added +* Added option to set different base url for API +### Fixed +* Fixed documentation +### Security +* Updated dependencies diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a76c2a..e21504f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,14 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), and is generated by [Changie](https://github.com/miniscruff/changie). +## v0.5.0 - 2024-04-19 +### Added +* Added option to set different base url for API +### Fixed +* Fixed documentation +### Security +* Updated dependencies + ## v0.4.0 - 2023-09-15 ### Added * Updated to go 1.21, updated documentation and metadata files From 43cb64cef57d674ef97961de1baf9749a2a081a2 Mon Sep 17 00:00:00 2001 From: "labd-project-manager[bot]" <141430439+labd-project-manager[bot]@users.noreply.github.com> Date: Fri, 3 May 2024 14:57:12 +0000 Subject: [PATCH 177/192] =?UTF-8?q?=F0=9F=94=84=20synced=20local=20'.githu?= =?UTF-8?q?b/'=20with=20remote=20'projects/go-terraform-provider/.github'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/ISSUE_TEMPLATE/bug-report.md | 19 +++++++++++++++++ .github/ISSUE_TEMPLATE/feature-request.md | 4 ++++ .github/ISSUE_TEMPLATE/support-request.md | 4 ++++ .github/dependabot.yaml | 26 +++++++++++++++++++++++ 4 files changed, 53 insertions(+) create mode 100644 .github/dependabot.yaml diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/.github/ISSUE_TEMPLATE/bug-report.md index 4a6f11f..043c105 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.md +++ b/.github/ISSUE_TEMPLATE/bug-report.md @@ -6,3 +6,22 @@ labels: bug, triage assignees: '' --- + +### Version information +- **terraform**: _Please specify the version of Terraform you are using._ +- **terraform provider**: _Please specify the version of the provider you are using._ + +### Describe the bug +A clear and concise description of what the bug is. + +### To Reproduce +Steps to reproduce the behavior. + +### Expected behavior +A clear and concise description of what you expected to happen. + +### Screenshots +If applicable, add screenshots to help explain your problem. + +### Additional context +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature-request.md b/.github/ISSUE_TEMPLATE/feature-request.md index 090c4a9..9ccf42b 100644 --- a/.github/ISSUE_TEMPLATE/feature-request.md +++ b/.github/ISSUE_TEMPLATE/feature-request.md @@ -6,3 +6,7 @@ labels: enhancement, triage assignees: '' --- + +Describe the feature you would like to see implemented. Please provide as much +detail as possible. If you have a specific use case, please provide that as +well. diff --git a/.github/ISSUE_TEMPLATE/support-request.md b/.github/ISSUE_TEMPLATE/support-request.md index ccb48bd..7744c64 100644 --- a/.github/ISSUE_TEMPLATE/support-request.md +++ b/.github/ISSUE_TEMPLATE/support-request.md @@ -6,3 +6,7 @@ labels: question, triage assignees: '' --- + +Describe your question here. Please provide as much detail as possible. If you +have a specific use case, please provide that as well. +``` diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml new file mode 100644 index 0000000..d2c2b03 --- /dev/null +++ b/.github/dependabot.yaml @@ -0,0 +1,26 @@ + +version: 2 +updates: + - package-ecosystem: "gomod" + directory: "/" + schedule: + interval: "weekly" + day: friday + commit-message: + prefix: "chore(deps)" + groups: + go: + patterns: + - "*" + + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + day: friday + commit-message: + prefix: "chore(deps)" + groups: + github-actions: + patterns: + - "*" From db1bf3fd93fabbff455aa08165dfd0ce164f14e5 Mon Sep 17 00:00:00 2001 From: "labd-project-manager[bot]" <141430439+labd-project-manager[bot]@users.noreply.github.com> Date: Tue, 7 May 2024 13:35:34 +0000 Subject: [PATCH 178/192] =?UTF-8?q?=F0=9F=94=84=20synced=20local=20'.githu?= =?UTF-8?q?b/'=20with=20remote=20'projects/go-terraform-provider/.github'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/dependabot-changie.yaml | 36 +++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 .github/workflows/dependabot-changie.yaml diff --git a/.github/workflows/dependabot-changie.yaml b/.github/workflows/dependabot-changie.yaml new file mode 100644 index 0000000..cb0c658 --- /dev/null +++ b/.github/workflows/dependabot-changie.yaml @@ -0,0 +1,36 @@ +name: Dependabot add changie file +on: + pull_request: + types: [opened] + +permissions: + pull-requests: write + issues: write + repository-projects: write + contents: write + +jobs: + dependabot-changie: + runs-on: ubuntu-latest + if: github.actor == 'dependabot[bot]' + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Fetch Dependabot metadata + id: dependabot-metadata + uses: dependabot/fetch-metadata@v2 + with: + github-token: "${{ secrets.GITHUB_TOKEN }}" + + - name: Create change file + uses: miniscruff/changie-action@v2 + with: + version: latest + args: new --body "${{ github.event.pull_request.title }}" --kind Dependency + + - uses: stefanzweifel/git-auto-commit-action@v5 + with: + commit_message: "chore(deps): add changelog for dependabot updates" + commit_user_name: "dependabot[bot]" + commit_user_email: "dependabot[bot]@users.noreply.github.com" From 8bc88ff1f98bd1616230ff626a1a97e042c4796e Mon Sep 17 00:00:00 2001 From: "labd-project-manager[bot]" <141430439+labd-project-manager[bot]@users.noreply.github.com> Date: Tue, 7 May 2024 13:35:36 +0000 Subject: [PATCH 179/192] =?UTF-8?q?=F0=9F=94=84=20synced=20local=20'.chang?= =?UTF-8?q?ie.yaml'=20with=20remote=20'projects/go-terraform-provider/.cha?= =?UTF-8?q?ngie.yaml'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .changie.yaml | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/.changie.yaml b/.changie.yaml index 906d495..704932a 100644 --- a/.changie.yaml +++ b/.changie.yaml @@ -7,18 +7,20 @@ versionFormat: '## {{.Version}} - {{.Time.Format "2006-01-02"}}' kindFormat: '### {{.Kind}}' changeFormat: '* {{.Body}}' kinds: -- label: Added - auto: minor -- label: Changed - auto: major -- label: Deprecated - auto: minor -- label: Removed - auto: major -- label: Fixed - auto: patch -- label: Security - auto: patch + - label: Added + auto: minor + - label: Changed + auto: major + - label: Deprecated + auto: minor + - label: Removed + auto: major + - label: Fixed + auto: patch + - label: Security + auto: patch + - label: Dependency + auto: patch newlines: afterChangelogHeader: 1 beforeChangelogVersion: 1 From 38b8ba05b940a0d040c05ba8f45f431f9a0b2087 Mon Sep 17 00:00:00 2001 From: "labd-project-manager[bot]" <141430439+labd-project-manager[bot]@users.noreply.github.com> Date: Fri, 10 May 2024 14:20:02 +0000 Subject: [PATCH 180/192] =?UTF-8?q?=F0=9F=94=84=20synced=20local=20'.githu?= =?UTF-8?q?b/'=20with=20remote=20'projects/go-terraform-provider/.github'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/dependabot.yaml | 5 ++--- .github/workflows/dependabot-changie.yaml | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml index d2c2b03..3e43501 100644 --- a/.github/dependabot.yaml +++ b/.github/dependabot.yaml @@ -1,11 +1,10 @@ - version: 2 updates: - package-ecosystem: "gomod" directory: "/" schedule: interval: "weekly" - day: friday + day: tuesday commit-message: prefix: "chore(deps)" groups: @@ -17,7 +16,7 @@ updates: directory: "/" schedule: interval: "weekly" - day: friday + day: tuesday commit-message: prefix: "chore(deps)" groups: diff --git a/.github/workflows/dependabot-changie.yaml b/.github/workflows/dependabot-changie.yaml index cb0c658..4346052 100644 --- a/.github/workflows/dependabot-changie.yaml +++ b/.github/workflows/dependabot-changie.yaml @@ -1,7 +1,7 @@ name: Dependabot add changie file on: pull_request: - types: [opened] + types: [opened, edited] permissions: pull-requests: write From c421212fa5befda9a3735fe24f8472d5b6e4cc47 Mon Sep 17 00:00:00 2001 From: "labd-project-manager[bot]" <141430439+labd-project-manager[bot]@users.noreply.github.com> Date: Fri, 10 May 2024 14:22:49 +0000 Subject: [PATCH 181/192] =?UTF-8?q?=F0=9F=94=84=20synced=20local=20'.githu?= =?UTF-8?q?b/'=20with=20remote=20'projects/go-terraform-provider/.github'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/dependabot-changie.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dependabot-changie.yaml b/.github/workflows/dependabot-changie.yaml index 4346052..cb0c658 100644 --- a/.github/workflows/dependabot-changie.yaml +++ b/.github/workflows/dependabot-changie.yaml @@ -1,7 +1,7 @@ name: Dependabot add changie file on: pull_request: - types: [opened, edited] + types: [opened] permissions: pull-requests: write From bf76f6baebd69b92a49e334969f8e72712262961 Mon Sep 17 00:00:00 2001 From: Thomas De Meyer Date: Fri, 7 Jun 2024 11:14:47 +0200 Subject: [PATCH 182/192] feat: support rich text fields --- .github/workflows/release.yaml | 6 +- .github/workflows/tests.yaml | 10 +-- contentful/errors.go | 34 ++++++++ contentful/errors_test.go | 69 ++++++++++++++++ contentful/provider_test.go | 5 +- contentful/resource_contentful_apikey.go | 50 +++++++----- contentful/resource_contentful_asset.go | 75 ++++++++++------- contentful/resource_contentful_contenttype.go | 61 ++++++++------ contentful/resource_contentful_entry.go | 80 ++++++++++++------- contentful/resource_contentful_entry_test.go | 66 +++++++++++++++ contentful/resource_contentful_environment.go | 52 +++++++----- contentful/resource_contentful_locale.go | 50 +++++++----- contentful/resource_contentful_space.go | 45 ++++++----- contentful/resource_contentful_webhook.go | 47 ++++++----- docs/resources/entry.md | 24 +++++- .../resources/contentful_entry/resource.tf | 24 +++++- go.mod | 3 + 17 files changed, 512 insertions(+), 189 deletions(-) create mode 100644 contentful/errors.go create mode 100644 contentful/errors_test.go diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 612af53..819bef2 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -7,14 +7,14 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 0 - name: Set up Go - uses: actions/setup-go@v4 + uses: actions/setup-go@v5 with: - go-version: "1.21" + go-version-file: 'go.mod' - name: Import GPG key id: import_gpg diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index abbc635..d2c600a 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -8,12 +8,12 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - - name: Set up Go 1.21 - uses: actions/setup-go@v2 + - name: Set up Go + uses: actions/setup-go@v5 with: - go-version: "1.21" + go-version-file: 'go.mod' - name: golangci-lint continue-on-error: true @@ -43,7 +43,7 @@ jobs: fetch-depth: 0 - name: Prepare release - uses: labd/changie-release-action@v0.2.0 + uses: labd/changie-release-action@v0.3.2 with: github-token: ${{ secrets.GITHUB_TOKEN }} release-workflow: 'release.yaml' diff --git a/contentful/errors.go b/contentful/errors.go new file mode 100644 index 0000000..5f227e4 --- /dev/null +++ b/contentful/errors.go @@ -0,0 +1,34 @@ +package contentful + +import ( + "errors" + "fmt" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/labd/contentful-go" + "strings" +) + +func parseError(err error) diag.Diagnostics { + if !errors.As(err, &contentful.ErrorResponse{}) { + return diag.FromErr(err) + } + + var warnings []diag.Diagnostic + for _, e := range err.(contentful.ErrorResponse).Details.Errors { + var path []string + if e.Path != nil { + for _, p := range e.Path.([]interface{}) { + path = append(path, fmt.Sprintf("%v", p)) + } + } + warnings = append(warnings, diag.Diagnostic{ + Severity: diag.Warning, + Summary: fmt.Sprintf("%s (%s)", e.Details, strings.Join(path, ".")), + }) + } + + return append(warnings, diag.Diagnostic{ + Severity: diag.Error, + Summary: err.(contentful.ErrorResponse).Message, + }) +} diff --git a/contentful/errors_test.go b/contentful/errors_test.go new file mode 100644 index 0000000..c3fd36f --- /dev/null +++ b/contentful/errors_test.go @@ -0,0 +1,69 @@ +package contentful + +import ( + "fmt" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/labd/contentful-go" + "github.com/stretchr/testify/assert" + "testing" +) + +func TestParseError_Nil(t *testing.T) { + d := parseError(nil) + assert.Nil(t, d) +} + +func TestParseError_RegularErr(t *testing.T) { + d := parseError(fmt.Errorf("regular error")) + assert.True(t, d.HasError()) + assert.Equal(t, d[0].Summary, "regular error") +} + +func TestParseError_WithoutWarning(t *testing.T) { + d := parseError(&contentful.ErrorResponse{ + Message: "error message", + }) + assert.True(t, d.HasError()) + assert.Equal(t, len(d), 1) + assert.Equal(t, d[0].Summary, "error message") + assert.Equal(t, d[0].Severity, diag.Error) +} + +func TestParseError_WithWarning_WithoutPath(t *testing.T) { + d := parseError(contentful.ErrorResponse{ + Message: "error message", + Details: &contentful.ErrorDetails{ + Errors: []*contentful.ErrorDetail{ + { + Details: "error detail", + }, + }, + }, + }) + assert.True(t, d.HasError()) + assert.Equal(t, len(d), 2) + assert.Equal(t, d[0].Summary, "error detail ()") + assert.Equal(t, d[0].Severity, diag.Warning) + assert.Equal(t, d[1].Summary, "error message") + assert.Equal(t, d[1].Severity, diag.Error) +} + +func TestParseError_WithWarning_WithPath(t *testing.T) { + d := parseError(contentful.ErrorResponse{ + Message: "error message", + Details: &contentful.ErrorDetails{ + Errors: []*contentful.ErrorDetail{ + { + Path: []interface{}{"path", "to", "error"}, + Details: "error detail", + }, + }, + }, + }) + assert.True(t, d.HasError()) + assert.Equal(t, len(d), 2) + assert.Equal(t, d[0].Summary, "error detail (path.to.error)") + assert.Equal(t, d[0].Severity, diag.Warning) + assert.Equal(t, d[1].Summary, "error message") + assert.Equal(t, d[1].Severity, diag.Error) +} diff --git a/contentful/provider_test.go b/contentful/provider_test.go index c9bd83e..dbd9a77 100644 --- a/contentful/provider_test.go +++ b/contentful/provider_test.go @@ -27,11 +27,14 @@ func TestProvider_impl(t *testing.T) { } func testAccPreCheck(t *testing.T) { - var cmaToken, organizationID string + var cmaToken, organizationID, sId string if cmaToken = CMAToken; cmaToken == "" { t.Fatal("CONTENTFUL_MANAGEMENT_TOKEN must set with a valid Contentful Content Management API Token for acceptance tests") } if organizationID = orgID; organizationID == "" { t.Fatal("CONTENTFUL_ORGANIZATION_ID must set with a valid Contentful Organization ID for acceptance tests") } + if sId = spaceID; sId == "" { + t.Fatal("SPACE_ID must set with a valid Space ID for acceptance tests") + } } diff --git a/contentful/resource_contentful_apikey.go b/contentful/resource_contentful_apikey.go index 1a9eda5..52d0456 100644 --- a/contentful/resource_contentful_apikey.go +++ b/contentful/resource_contentful_apikey.go @@ -1,6 +1,9 @@ package contentful import ( + "context" + "errors" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/labd/contentful-go" ) @@ -9,10 +12,10 @@ func resourceContentfulAPIKey() *schema.Resource { return &schema.Resource{ Description: "A Contentful API Key represents a token that can be used to authenticate against the Contentful Content Delivery API and Content Preview API.", - Create: resourceCreateAPIKey, - Read: resourceReadAPIKey, - Update: resourceUpdateAPIKey, - Delete: resourceDeleteAPIKey, + CreateContext: resourceCreateAPIKey, + ReadContext: resourceReadAPIKey, + UpdateContext: resourceUpdateAPIKey, + DeleteContext: resourceDeleteAPIKey, Schema: map[string]*schema.Schema{ "version": { @@ -39,7 +42,7 @@ func resourceContentfulAPIKey() *schema.Resource { } } -func resourceCreateAPIKey(d *schema.ResourceData, m interface{}) (err error) { +func resourceCreateAPIKey(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { client := m.(*contentful.Client) apiKey := &contentful.APIKey{ @@ -47,13 +50,13 @@ func resourceCreateAPIKey(d *schema.ResourceData, m interface{}) (err error) { Description: d.Get("description").(string), } - err = client.APIKeys.Upsert(d.Get("space_id").(string), apiKey) + err := client.APIKeys.Upsert(d.Get("space_id").(string), apiKey) if err != nil { - return err + return parseError(err) } if err := setAPIKeyProperties(d, apiKey); err != nil { - return err + return parseError(err) } d.SetId(apiKey.Sys.ID) @@ -61,14 +64,14 @@ func resourceCreateAPIKey(d *schema.ResourceData, m interface{}) (err error) { return nil } -func resourceUpdateAPIKey(d *schema.ResourceData, m interface{}) (err error) { +func resourceUpdateAPIKey(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) apiKeyID := d.Id() apiKey, err := client.APIKeys.Get(spaceID, apiKeyID) if err != nil { - return err + return parseError(err) } apiKey.Name = d.Get("name").(string) @@ -76,11 +79,11 @@ func resourceUpdateAPIKey(d *schema.ResourceData, m interface{}) (err error) { err = client.APIKeys.Upsert(spaceID, apiKey) if err != nil { - return err + return parseError(err) } if err := setAPIKeyProperties(d, apiKey); err != nil { - return err + return parseError(err) } d.SetId(apiKey.Sys.ID) @@ -88,31 +91,42 @@ func resourceUpdateAPIKey(d *schema.ResourceData, m interface{}) (err error) { return nil } -func resourceReadAPIKey(d *schema.ResourceData, m interface{}) (err error) { +func resourceReadAPIKey(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) apiKeyID := d.Id() apiKey, err := client.APIKeys.Get(spaceID, apiKeyID) - if _, ok := err.(contentful.NotFoundError); ok { + var notFoundError contentful.NotFoundError + if errors.As(err, ¬FoundError) { d.SetId("") return nil } - return setAPIKeyProperties(d, apiKey) + err = setAPIKeyProperties(d, apiKey) + if err != nil { + return parseError(err) + } + + return nil } -func resourceDeleteAPIKey(d *schema.ResourceData, m interface{}) (err error) { +func resourceDeleteAPIKey(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) apiKeyID := d.Id() apiKey, err := client.APIKeys.Get(spaceID, apiKeyID) if err != nil { - return err + return parseError(err) } - return client.APIKeys.Delete(spaceID, apiKey) + err = client.APIKeys.Delete(spaceID, apiKey) + if err != nil { + return parseError(err) + } + + return nil } func setAPIKeyProperties(d *schema.ResourceData, apiKey *contentful.APIKey) error { diff --git a/contentful/resource_contentful_asset.go b/contentful/resource_contentful_asset.go index f3e3617..016b7fc 100644 --- a/contentful/resource_contentful_asset.go +++ b/contentful/resource_contentful_asset.go @@ -1,7 +1,9 @@ package contentful import ( - "fmt" + "context" + "errors" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "time" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" @@ -10,11 +12,11 @@ import ( func resourceContentfulAsset() *schema.Resource { return &schema.Resource{ - Description: "A Contentful Asset represents a file that can be used in entries.", - Create: resourceCreateAsset, - Read: resourceReadAsset, - Update: resourceUpdateAsset, - Delete: resourceDeleteAsset, + Description: "A Contentful Asset represents a file that can be used in entries.", + CreateContext: resourceCreateAsset, + ReadContext: resourceReadAsset, + UpdateContext: resourceUpdateAsset, + DeleteContext: resourceDeleteAsset, Schema: map[string]*schema.Schema{ "asset_id": { @@ -142,7 +144,7 @@ func resourceContentfulAsset() *schema.Resource { } } -func resourceCreateAsset(d *schema.ResourceData, m interface{}) (err error) { +func resourceCreateAsset(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { client := m.(*contentful.Client) fields := d.Get("fields").([]interface{})[0].(map[string]interface{}) @@ -164,7 +166,7 @@ func resourceCreateAsset(d *schema.ResourceData, m interface{}) (err error) { files := fields["file"].([]interface{}) if len(files) == 0 { - return fmt.Errorf("file block not defined in asset") + return diag.Errorf("file block not defined in asset") } file := files[0].(map[string]interface{}) @@ -207,37 +209,37 @@ func resourceCreateAsset(d *schema.ResourceData, m interface{}) (err error) { } } - if err = client.Assets.Upsert(d.Get("space_id").(string), asset); err != nil { - return err + if err := client.Assets.Upsert(d.Get("space_id").(string), asset); err != nil { + return parseError(err) } - if err = client.Assets.Process(d.Get("space_id").(string), asset); err != nil { - return err + if err := client.Assets.Process(d.Get("space_id").(string), asset); err != nil { + return parseError(err) } d.SetId(asset.Sys.ID) if err := setAssetProperties(d, asset); err != nil { - return err + return parseError(err) } time.Sleep(1 * time.Second) // avoid race conditions with version mismatches - if err = setAssetState(d, m); err != nil { - return err + if err := setAssetState(d, m); err != nil { + return parseError(err) } - return err + return nil } -func resourceUpdateAsset(d *schema.ResourceData, m interface{}) (err error) { +func resourceUpdateAsset(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) assetID := d.Id() - _, err = client.Assets.Get(spaceID, assetID) + _, err := client.Assets.Get(spaceID, assetID) if err != nil { - return err + return parseError(err) } fields := d.Get("fields").([]interface{})[0].(map[string]interface{}) @@ -259,7 +261,7 @@ func resourceUpdateAsset(d *schema.ResourceData, m interface{}) (err error) { files := fields["file"].([]interface{}) if len(files) == 0 { - return fmt.Errorf("file block not defined in asset") + return diag.Errorf("file block not defined in asset") } file := files[0].(map[string]interface{}) @@ -303,24 +305,24 @@ func resourceUpdateAsset(d *schema.ResourceData, m interface{}) (err error) { } if err := client.Assets.Upsert(d.Get("space_id").(string), asset); err != nil { - return err + return parseError(err) } if err = client.Assets.Process(d.Get("space_id").(string), asset); err != nil { - return err + return parseError(err) } d.SetId(asset.Sys.ID) if err := setAssetProperties(d, asset); err != nil { - return err + return parseError(err) } if err = setAssetState(d, m); err != nil { - return err + return parseError(err) } - return err + return nil } func setAssetState(d *schema.ResourceData, m interface{}) (err error) { @@ -354,31 +356,42 @@ func setAssetState(d *schema.ResourceData, m interface{}) (err error) { return err } -func resourceReadAsset(d *schema.ResourceData, m interface{}) (err error) { +func resourceReadAsset(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) assetID := d.Id() asset, err := client.Assets.Get(spaceID, assetID) - if _, ok := err.(contentful.NotFoundError); ok { + var notFoundError contentful.NotFoundError + if errors.As(err, ¬FoundError) { d.SetId("") return nil } - return setAssetProperties(d, asset) + err = setAssetProperties(d, asset) + if err != nil { + return parseError(err) + } + + return nil } -func resourceDeleteAsset(d *schema.ResourceData, m interface{}) (err error) { +func resourceDeleteAsset(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) assetID := d.Id() asset, err := client.Assets.Get(spaceID, assetID) if err != nil { - return err + return parseError(err) + } + + err = client.Assets.Delete(spaceID, asset) + if err != nil { + return parseError(err) } - return client.Assets.Delete(spaceID, asset) + return nil } func setAssetProperties(d *schema.ResourceData, asset *contentful.Asset) (err error) { diff --git a/contentful/resource_contentful_contenttype.go b/contentful/resource_contentful_contenttype.go index 0051a0a..198fc3a 100644 --- a/contentful/resource_contentful_contenttype.go +++ b/contentful/resource_contentful_contenttype.go @@ -1,6 +1,8 @@ package contentful import ( + "context" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/labd/contentful-go" ) @@ -9,10 +11,10 @@ func resourceContentfulContentType() *schema.Resource { return &schema.Resource{ Description: "A Contentful Content Type represents a structure for entries.", - Create: resourceContentTypeCreate, - Read: resourceContentTypeRead, - Update: resourceContentTypeUpdate, - Delete: resourceContentTypeDelete, + CreateContext: resourceContentTypeCreate, + ReadContext: resourceContentTypeRead, + UpdateContext: resourceContentTypeUpdate, + DeleteContext: resourceContentTypeDelete, Schema: map[string]*schema.Schema{ "space_id": { @@ -111,7 +113,7 @@ func resourceContentfulContentType() *schema.Resource { } } -func resourceContentTypeCreate(d *schema.ResourceData, m interface{}) (err error) { +func resourceContentTypeCreate(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) @@ -146,7 +148,7 @@ func resourceContentTypeCreate(d *schema.ResourceData, m interface{}) (err error if validations, ok := field["validations"].([]interface{}); ok { parsedValidations, err := contentful.ParseValidations(validations) if err != nil { - return err + return parseError(err) } contentfulField.Validations = parsedValidations @@ -159,16 +161,16 @@ func resourceContentTypeCreate(d *schema.ResourceData, m interface{}) (err error ct.Fields = append(ct.Fields, contentfulField) } - if err = client.ContentTypes.Upsert(spaceID, ct); err != nil { - return err + if err := client.ContentTypes.Upsert(spaceID, ct); err != nil { + return parseError(err) } - if err = client.ContentTypes.Activate(spaceID, ct); err != nil { - return err + if err := client.ContentTypes.Activate(spaceID, ct); err != nil { + return parseError(err) } - if err = setContentTypeProperties(d, ct); err != nil { - return err + if err := setContentTypeProperties(d, ct); err != nil { + return parseError(err) } d.SetId(ct.Sys.ID) @@ -176,16 +178,19 @@ func resourceContentTypeCreate(d *schema.ResourceData, m interface{}) (err error return nil } -func resourceContentTypeRead(d *schema.ResourceData, m interface{}) (err error) { +func resourceContentTypeRead(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) - _, err = client.ContentTypes.Get(spaceID, d.Id()) + _, err := client.ContentTypes.Get(spaceID, d.Id()) + if err != nil { + return parseError(err) + } - return err + return nil } -func resourceContentTypeUpdate(d *schema.ResourceData, m interface{}) (err error) { +func resourceContentTypeUpdate(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { var existingFields []*contentful.Field var deletedFields []*contentful.Field @@ -194,7 +199,7 @@ func resourceContentTypeUpdate(d *schema.ResourceData, m interface{}) (err error ct, err := client.ContentTypes.Get(spaceID, d.Id()) if err != nil { - return err + return parseError(err) } ct.Name = d.Get("name").(string) @@ -220,44 +225,48 @@ func resourceContentTypeUpdate(d *schema.ResourceData, m interface{}) (err error // Omit the removed fields and publish the new version of the content type, // followed by the field removal and final publish. if err = client.ContentTypes.Upsert(spaceID, ct); err != nil { - return err + return parseError(err) } if err = client.ContentTypes.Activate(spaceID, ct); err != nil { - return err + return parseError(err) } if deletedFields != nil { ct.Fields = existingFields if err = client.ContentTypes.Upsert(spaceID, ct); err != nil { - return err + return parseError(err) } if err = client.ContentTypes.Activate(spaceID, ct); err != nil { - return err + return parseError(err) } } - return setContentTypeProperties(d, ct) + if err = setContentTypeProperties(d, ct); err != nil { + return parseError(err) + } + + return nil } -func resourceContentTypeDelete(d *schema.ResourceData, m interface{}) (err error) { +func resourceContentTypeDelete(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) ct, err := client.ContentTypes.Get(spaceID, d.Id()) if err != nil { - return err + return parseError(err) } err = client.ContentTypes.Deactivate(spaceID, ct) if err != nil { - return err + return parseError(err) } if err = client.ContentTypes.Delete(spaceID, ct); err != nil { - return err + return parseError(err) } return nil diff --git a/contentful/resource_contentful_entry.go b/contentful/resource_contentful_entry.go index f302f9e..6f63af7 100644 --- a/contentful/resource_contentful_entry.go +++ b/contentful/resource_contentful_entry.go @@ -1,6 +1,10 @@ package contentful import ( + "context" + "encoding/json" + "errors" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/labd/contentful-go" ) @@ -9,10 +13,10 @@ func resourceContentfulEntry() *schema.Resource { return &schema.Resource{ Description: "A Contentful Entry represents a piece of content in a space.", - Create: resourceCreateEntry, - Read: resourceReadEntry, - Update: resourceUpdateEntry, - Delete: resourceDeleteEntry, + CreateContext: resourceCreateEntry, + ReadContext: resourceReadEntry, + UpdateContext: resourceUpdateEntry, + DeleteContext: resourceDeleteEntry, Schema: map[string]*schema.Schema{ "entry_id": { @@ -45,8 +49,9 @@ func resourceContentfulEntry() *schema.Resource { Required: true, }, "content": { - Type: schema.TypeString, - Required: true, + Type: schema.TypeString, + Required: true, + Description: "The content of the field. If the field type is Richtext the content can be passed as stringified JSON (see example).", }, "locale": { Type: schema.TypeString, @@ -67,7 +72,7 @@ func resourceContentfulEntry() *schema.Resource { } } -func resourceCreateEntry(d *schema.ResourceData, m interface{}) (err error) { +func resourceCreateEntry(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { client := m.(*contentful.Client) fieldProperties := map[string]interface{}{} @@ -75,7 +80,7 @@ func resourceCreateEntry(d *schema.ResourceData, m interface{}) (err error) { for i := 0; i < len(rawField); i++ { field := rawField[i].(map[string]interface{}) fieldProperties[field["id"].(string)] = map[string]interface{}{} - fieldProperties[field["id"].(string)].(map[string]interface{})[field["locale"].(string)] = field["content"].(string) + fieldProperties[field["id"].(string)].(map[string]interface{})[field["locale"].(string)] = parseContentValue(field["content"].(string)) } entry := &contentful.Entry{ @@ -86,32 +91,32 @@ func resourceCreateEntry(d *schema.ResourceData, m interface{}) (err error) { }, } - err = client.Entries.Upsert(d.Get("space_id").(string), d.Get("contenttype_id").(string), entry) + err := client.Entries.Upsert(d.Get("space_id").(string), d.Get("contenttype_id").(string), entry) if err != nil { - return err + return parseError(err) } if err := setEntryProperties(d, entry); err != nil { - return err + return parseError(err) } d.SetId(entry.Sys.ID) if err := setEntryState(d, m); err != nil { - return err + return parseError(err) } - return err + return parseError(err) } -func resourceUpdateEntry(d *schema.ResourceData, m interface{}) (err error) { +func resourceUpdateEntry(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) entryID := d.Id() entry, err := client.Entries.Get(spaceID, entryID) if err != nil { - return err + return parseError(err) } fieldProperties := map[string]interface{}{} @@ -119,7 +124,7 @@ func resourceUpdateEntry(d *schema.ResourceData, m interface{}) (err error) { for i := 0; i < len(rawField); i++ { field := rawField[i].(map[string]interface{}) fieldProperties[field["id"].(string)] = map[string]interface{}{} - fieldProperties[field["id"].(string)].(map[string]interface{})[field["locale"].(string)] = field["content"].(string) + fieldProperties[field["id"].(string)].(map[string]interface{})[field["locale"].(string)] = parseContentValue(field["content"].(string)) } entry.Fields = fieldProperties @@ -127,20 +132,20 @@ func resourceUpdateEntry(d *schema.ResourceData, m interface{}) (err error) { err = client.Entries.Upsert(d.Get("space_id").(string), d.Get("contenttype_id").(string), entry) if err != nil { - return err + return parseError(err) } d.SetId(entry.Sys.ID) if err := setEntryProperties(d, entry); err != nil { - return err + return parseError(err) } if err := setEntryState(d, m); err != nil { - return err + return parseError(err) } - return err + return nil } func setEntryState(d *schema.ResourceData, m interface{}) (err error) { @@ -165,31 +170,42 @@ func setEntryState(d *schema.ResourceData, m interface{}) (err error) { return err } -func resourceReadEntry(d *schema.ResourceData, m interface{}) (err error) { +func resourceReadEntry(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) entryID := d.Id() entry, err := client.Entries.Get(spaceID, entryID) - if _, ok := err.(contentful.NotFoundError); ok { + var notFoundError contentful.NotFoundError + if errors.As(err, ¬FoundError) { d.SetId("") return nil } - return setEntryProperties(d, entry) + err = setEntryProperties(d, entry) + if err != nil { + return parseError(err) + } + + return nil } -func resourceDeleteEntry(d *schema.ResourceData, m interface{}) (err error) { +func resourceDeleteEntry(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) entryID := d.Id() - _, err = client.Entries.Get(spaceID, entryID) + _, err := client.Entries.Get(spaceID, entryID) if err != nil { - return err + return parseError(err) + } + + err = client.Entries.Delete(spaceID, entryID) + if err != nil { + return parseError(err) } - return client.Entries.Delete(spaceID, entryID) + return nil } func setEntryProperties(d *schema.ResourceData, entry *contentful.Entry) (err error) { @@ -207,3 +223,13 @@ func setEntryProperties(d *schema.ResourceData, entry *contentful.Entry) (err er return err } + +func parseContentValue(value interface{}) interface{} { + var content interface{} + err := json.Unmarshal([]byte(value.(string)), &content) + if err != nil { + content = value + } + + return content +} diff --git a/contentful/resource_contentful_entry_test.go b/contentful/resource_contentful_entry_test.go index 30c7cb7..b4cfb86 100644 --- a/contentful/resource_contentful_entry_test.go +++ b/contentful/resource_contentful_entry_test.go @@ -2,6 +2,7 @@ package contentful import ( "fmt" + "github.com/stretchr/testify/assert" "testing" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" @@ -9,6 +10,16 @@ import ( contentful "github.com/labd/contentful-go" ) +func TestParseContentValue_String(t *testing.T) { + value := "hello" + assert.Equal(t, parseContentValue(value), value) +} + +func TestParseContentValue_Json(t *testing.T) { + value := `{"foo": "bar", "baz": [1, 2, 3]}` + assert.Equal(t, parseContentValue(value), map[string]interface{}{"foo": "bar", "baz": []interface{}{float64(1), float64(2), float64(3)}}) +} + func TestAccContentfulEntry_Basic(t *testing.T) { var entry contentful.Entry @@ -136,6 +147,11 @@ resource "contentful_contenttype" "mycontenttype" { required = true type = "Text" } + field { + id = "field3" + name = "Field 3" + type = "RichText" + } } resource "contentful_entry" "myentry" { @@ -153,6 +169,29 @@ resource "contentful_entry" "myentry" { content = "Bacon is healthy!" locale = "en-US" } + + field { + id = "field3" + locale = "en-US" + content = jsonencode({ + data= {}, + content= [ + { + nodeType= "paragraph", + content= [ + { + nodeType= "text", + marks= [], + value= "This is another paragraph.", + data= {}, + }, + ], + data= {}, + } + ], + nodeType= "document" + }) + } published = true archived = false depends_on = [contentful_contenttype.mycontenttype] @@ -183,6 +222,11 @@ resource "contentful_contenttype" "mycontenttype" { required = true type = "Text" } + field { + id = "field3" + name = "Field 3" + type = "RichText" + } } resource "contentful_entry" "myentry" { @@ -200,6 +244,28 @@ resource "contentful_entry" "myentry" { content = "Bacon is healthy!" locale = "en-US" } + field { + id = "field3" + locale = "en-US" + content = jsonencode({ + data= {}, + content= [ + { + nodeType= "paragraph", + content= [ + { + nodeType= "text", + marks= [], + value= "This is another paragraph.", + data= {}, + }, + ], + data= {}, + } + ], + nodeType= "document" + }) + } published = false archived = false depends_on = [contentful_contenttype.mycontenttype] diff --git a/contentful/resource_contentful_environment.go b/contentful/resource_contentful_environment.go index 097cc5e..fbf64d7 100644 --- a/contentful/resource_contentful_environment.go +++ b/contentful/resource_contentful_environment.go @@ -1,17 +1,20 @@ package contentful import ( + "context" + "errors" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/labd/contentful-go" ) func resourceContentfulEnvironment() *schema.Resource { return &schema.Resource{ - Description: "A Contentful Environment represents a space environment.", - Create: resourceCreateEnvironment, - Read: resourceReadEnvironment, - Update: resourceUpdateEnvironment, - Delete: resourceDeleteEnvironment, + Description: "A Contentful Environment represents a space environment.", + CreateContext: resourceCreateEnvironment, + ReadContext: resourceReadEnvironment, + UpdateContext: resourceUpdateEnvironment, + DeleteContext: resourceDeleteEnvironment, Schema: map[string]*schema.Schema{ "version": { @@ -30,20 +33,20 @@ func resourceContentfulEnvironment() *schema.Resource { } } -func resourceCreateEnvironment(d *schema.ResourceData, m interface{}) (err error) { +func resourceCreateEnvironment(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { client := m.(*contentful.Client) environment := &contentful.Environment{ Name: d.Get("name").(string), } - err = client.Environments.Upsert(d.Get("space_id").(string), environment) + err := client.Environments.Upsert(d.Get("space_id").(string), environment) if err != nil { - return err + return parseError(err) } if err := setEnvironmentProperties(d, environment); err != nil { - return err + return parseError(err) } d.SetId(environment.Name) @@ -51,25 +54,25 @@ func resourceCreateEnvironment(d *schema.ResourceData, m interface{}) (err error return nil } -func resourceUpdateEnvironment(d *schema.ResourceData, m interface{}) (err error) { +func resourceUpdateEnvironment(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) environmentID := d.Id() environment, err := client.Environments.Get(spaceID, environmentID) if err != nil { - return err + return parseError(err) } environment.Name = d.Get("name").(string) err = client.Environments.Upsert(spaceID, environment) if err != nil { - return err + return parseError(err) } if err := setEnvironmentProperties(d, environment); err != nil { - return err + return parseError(err) } d.SetId(environment.Sys.ID) @@ -77,31 +80,42 @@ func resourceUpdateEnvironment(d *schema.ResourceData, m interface{}) (err error return nil } -func resourceReadEnvironment(d *schema.ResourceData, m interface{}) (err error) { +func resourceReadEnvironment(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) environmentID := d.Id() environment, err := client.Environments.Get(spaceID, environmentID) - if _, ok := err.(contentful.NotFoundError); ok { + var notFoundError contentful.NotFoundError + if errors.As(err, ¬FoundError) { d.SetId("") return nil } - return setEnvironmentProperties(d, environment) + err = setEnvironmentProperties(d, environment) + if err != nil { + return parseError(err) + } + + return nil } -func resourceDeleteEnvironment(d *schema.ResourceData, m interface{}) (err error) { +func resourceDeleteEnvironment(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) environmentID := d.Id() environment, err := client.Environments.Get(spaceID, environmentID) if err != nil { - return err + return parseError(err) } - return client.Environments.Delete(spaceID, environment) + err = client.Environments.Delete(spaceID, environment) + if err != nil { + return parseError(err) + } + + return nil } func setEnvironmentProperties(d *schema.ResourceData, environment *contentful.Environment) error { diff --git a/contentful/resource_contentful_locale.go b/contentful/resource_contentful_locale.go index 755bc46..f6d8104 100644 --- a/contentful/resource_contentful_locale.go +++ b/contentful/resource_contentful_locale.go @@ -1,6 +1,9 @@ package contentful import ( + "context" + "errors" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/labd/contentful-go" ) @@ -9,10 +12,10 @@ func resourceContentfulLocale() *schema.Resource { return &schema.Resource{ Description: "A Contentful Locale represents a language and region combination.", - Create: resourceCreateLocale, - Read: resourceReadLocale, - Update: resourceUpdateLocale, - Delete: resourceDeleteLocale, + CreateContext: resourceCreateLocale, + ReadContext: resourceReadLocale, + UpdateContext: resourceUpdateLocale, + DeleteContext: resourceDeleteLocale, Schema: map[string]*schema.Schema{ "version": { @@ -55,7 +58,7 @@ func resourceContentfulLocale() *schema.Resource { } } -func resourceCreateLocale(d *schema.ResourceData, m interface{}) (err error) { +func resourceCreateLocale(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) @@ -68,14 +71,14 @@ func resourceCreateLocale(d *schema.ResourceData, m interface{}) (err error) { CMA: d.Get("cma").(bool), } - err = client.Locales.Upsert(spaceID, locale) + err := client.Locales.Upsert(spaceID, locale) if err != nil { - return err + return parseError(err) } err = setLocaleProperties(d, locale) if err != nil { - return err + return parseError(err) } d.SetId(locale.Sys.ID) @@ -83,32 +86,38 @@ func resourceCreateLocale(d *schema.ResourceData, m interface{}) (err error) { return nil } -func resourceReadLocale(d *schema.ResourceData, m interface{}) error { +func resourceReadLocale(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) localeID := d.Id() locale, err := client.Locales.Get(spaceID, localeID) - if _, ok := err.(*contentful.NotFoundError); ok { + var notFoundError *contentful.NotFoundError + if errors.As(err, ¬FoundError) { d.SetId("") return nil } if err != nil { - return err + return parseError(err) + } + + err = setLocaleProperties(d, locale) + if err != nil { + return parseError(err) } - return setLocaleProperties(d, locale) + return nil } -func resourceUpdateLocale(d *schema.ResourceData, m interface{}) (err error) { +func resourceUpdateLocale(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) localeID := d.Id() locale, err := client.Locales.Get(spaceID, localeID) if err != nil { - return err + return parseError(err) } locale.Name = d.Get("name").(string) @@ -120,34 +129,35 @@ func resourceUpdateLocale(d *schema.ResourceData, m interface{}) (err error) { err = client.Locales.Upsert(spaceID, locale) if err != nil { - return err + return parseError(err) } err = setLocaleProperties(d, locale) if err != nil { - return err + return parseError(err) } return nil } -func resourceDeleteLocale(d *schema.ResourceData, m interface{}) (err error) { +func resourceDeleteLocale(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) localeID := d.Id() locale, err := client.Locales.Get(spaceID, localeID) if err != nil { - return err + return parseError(err) } err = client.Locales.Delete(spaceID, locale) - if _, ok := err.(*contentful.NotFoundError); ok { + var notFoundError *contentful.NotFoundError + if errors.As(err, ¬FoundError) { return nil } if err != nil { - return err + return parseError(err) } return nil diff --git a/contentful/resource_contentful_space.go b/contentful/resource_contentful_space.go index 36bc188..c159bb5 100644 --- a/contentful/resource_contentful_space.go +++ b/contentful/resource_contentful_space.go @@ -1,6 +1,9 @@ package contentful import ( + "context" + "errors" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/labd/contentful-go" ) @@ -9,10 +12,10 @@ func resourceContentfulSpace() *schema.Resource { return &schema.Resource{ Description: "A Contentful Space represents a space in Contentful.", - Create: resourceSpaceCreate, - Read: resourceSpaceRead, - Update: resourceSpaceUpdate, - Delete: resourceSpaceDelete, + CreateContext: resourceSpaceCreate, + ReadContext: resourceSpaceRead, + UpdateContext: resourceSpaceUpdate, + DeleteContext: resourceSpaceDelete, Schema: map[string]*schema.Schema{ "version": { @@ -33,7 +36,7 @@ func resourceContentfulSpace() *schema.Resource { } } -func resourceSpaceCreate(d *schema.ResourceData, m interface{}) (err error) { +func resourceSpaceCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { client := m.(*contentful.Client) space := &contentful.Space{ @@ -41,14 +44,14 @@ func resourceSpaceCreate(d *schema.ResourceData, m interface{}) (err error) { DefaultLocale: d.Get("default_locale").(string), } - err = client.Spaces.Upsert(space) + err := client.Spaces.Upsert(space) if err != nil { - return err + return parseError(err) } err = updateSpaceProperties(d, space) if err != nil { - return err + return parseError(err) } d.SetId(space.Sys.ID) @@ -56,45 +59,51 @@ func resourceSpaceCreate(d *schema.ResourceData, m interface{}) (err error) { return nil } -func resourceSpaceRead(d *schema.ResourceData, m interface{}) error { +func resourceSpaceRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { client := m.(*contentful.Client) spaceID := d.Id() _, err := client.Spaces.Get(spaceID) - if _, ok := err.(contentful.NotFoundError); ok { + var notFoundError contentful.NotFoundError + if errors.As(err, ¬FoundError) { d.SetId("") return nil } - return err + return parseError(err) } -func resourceSpaceUpdate(d *schema.ResourceData, m interface{}) (err error) { +func resourceSpaceUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { client := m.(*contentful.Client) spaceID := d.Id() space, err := client.Spaces.Get(spaceID) if err != nil { - return err + return parseError(err) } space.Name = d.Get("name").(string) err = client.Spaces.Upsert(space) if err != nil { - return err + return parseError(err) } - return updateSpaceProperties(d, space) + err = updateSpaceProperties(d, space) + if err != nil { + return parseError(err) + } + + return nil } -func resourceSpaceDelete(d *schema.ResourceData, m interface{}) (err error) { +func resourceSpaceDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { client := m.(*contentful.Client) spaceID := d.Id() space, err := client.Spaces.Get(spaceID) if err != nil { - return err + return parseError(err) } err = client.Spaces.Delete(space) @@ -102,7 +111,7 @@ func resourceSpaceDelete(d *schema.ResourceData, m interface{}) (err error) { return nil } - return err + return parseError(err) } func updateSpaceProperties(d *schema.ResourceData, space *contentful.Space) error { diff --git a/contentful/resource_contentful_webhook.go b/contentful/resource_contentful_webhook.go index e74b749..49b500d 100644 --- a/contentful/resource_contentful_webhook.go +++ b/contentful/resource_contentful_webhook.go @@ -1,6 +1,9 @@ package contentful import ( + "context" + "errors" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/labd/contentful-go" ) @@ -9,10 +12,10 @@ func resourceContentfulWebhook() *schema.Resource { return &schema.Resource{ Description: "A Contentful Webhook represents a webhook that can be used to notify external services of changes in a space.", - Create: resourceCreateWebhook, - Read: resourceReadWebhook, - Update: resourceUpdateWebhook, - Delete: resourceDeleteWebhook, + CreateContext: resourceCreateWebhook, + ReadContext: resourceReadWebhook, + UpdateContext: resourceUpdateWebhook, + DeleteContext: resourceDeleteWebhook, Schema: map[string]*schema.Schema{ "version": { @@ -58,7 +61,7 @@ func resourceContentfulWebhook() *schema.Resource { } } -func resourceCreateWebhook(d *schema.ResourceData, m interface{}) (err error) { +func resourceCreateWebhook(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) @@ -71,14 +74,14 @@ func resourceCreateWebhook(d *schema.ResourceData, m interface{}) (err error) { HTTPBasicPassword: d.Get("http_basic_auth_password").(string), } - err = client.Webhooks.Upsert(spaceID, webhook) + err := client.Webhooks.Upsert(spaceID, webhook) if err != nil { - return err + return parseError(err) } err = setWebhookProperties(d, webhook) if err != nil { - return err + return parseError(err) } d.SetId(webhook.Sys.ID) @@ -86,14 +89,14 @@ func resourceCreateWebhook(d *schema.ResourceData, m interface{}) (err error) { return nil } -func resourceUpdateWebhook(d *schema.ResourceData, m interface{}) (err error) { +func resourceUpdateWebhook(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) webhookID := d.Id() webhook, err := client.Webhooks.Get(spaceID, webhookID) if err != nil { - return err + return parseError(err) } webhook.Name = d.Get("name").(string) @@ -105,12 +108,12 @@ func resourceUpdateWebhook(d *schema.ResourceData, m interface{}) (err error) { err = client.Webhooks.Upsert(spaceID, webhook) if err != nil { - return err + return parseError(err) } err = setWebhookProperties(d, webhook) if err != nil { - return err + return parseError(err) } d.SetId(webhook.Sys.ID) @@ -118,32 +121,38 @@ func resourceUpdateWebhook(d *schema.ResourceData, m interface{}) (err error) { return nil } -func resourceReadWebhook(d *schema.ResourceData, m interface{}) error { +func resourceReadWebhook(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) webhookID := d.Id() webhook, err := client.Webhooks.Get(spaceID, webhookID) - if _, ok := err.(contentful.NotFoundError); ok { + var notFoundError contentful.NotFoundError + if errors.As(err, ¬FoundError) { d.SetId("") return nil } if err != nil { - return err + return parseError(err) } - return setWebhookProperties(d, webhook) + err = setWebhookProperties(d, webhook) + if err != nil { + return parseError(err) + } + + return nil } -func resourceDeleteWebhook(d *schema.ResourceData, m interface{}) (err error) { +func resourceDeleteWebhook(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { client := m.(*contentful.Client) spaceID := d.Get("space_id").(string) webhookID := d.Id() webhook, err := client.Webhooks.Get(spaceID, webhookID) if err != nil { - return err + return parseError(err) } err = client.Webhooks.Delete(spaceID, webhook) @@ -151,7 +160,7 @@ func resourceDeleteWebhook(d *schema.ResourceData, m interface{}) (err error) { return nil } - return err + return parseError(err) } func setWebhookProperties(d *schema.ResourceData, webhook *contentful.Webhook) (err error) { diff --git a/docs/resources/entry.md b/docs/resources/entry.md index 61233ec..73c72ef 100644 --- a/docs/resources/entry.md +++ b/docs/resources/entry.md @@ -28,6 +28,28 @@ resource "contentful_entry" "example_entry" { content = "Lettuce is healthy!" locale = "en-US" } + field { + id = "content" + locale = "en-US" + content = jsonencode({ + data = {}, + content = [ + { + nodeType = "paragraph", + content = [ + { + nodeType = "text", + marks = [], + value = "This is a paragraph", + data = {}, + }, + ], + data = {}, + } + ], + nodeType = "document" + }) + } published = false archived = false depends_on = [contentful_contenttype.mycontenttype] @@ -57,7 +79,7 @@ resource "contentful_entry" "example_entry" { Required: -- `content` (String) +- `content` (String) The content of the field. If the field type is Richtext the content can be passed as stringified JSON (see example). - `locale` (String) Read-Only: diff --git a/examples/resources/contentful_entry/resource.tf b/examples/resources/contentful_entry/resource.tf index c1ebf51..c556074 100644 --- a/examples/resources/contentful_entry/resource.tf +++ b/examples/resources/contentful_entry/resource.tf @@ -13,7 +13,29 @@ resource "contentful_entry" "example_entry" { content = "Lettuce is healthy!" locale = "en-US" } + field { + id = "content" + locale = "en-US" + content = jsonencode({ + data = {}, + content = [ + { + nodeType = "paragraph", + content = [ + { + nodeType = "text", + marks = [], + value = "This is a paragraph", + data = {}, + }, + ], + data = {}, + } + ], + nodeType = "document" + }) + } published = false archived = false depends_on = [contentful_contenttype.mycontenttype] -} \ No newline at end of file +} diff --git a/go.mod b/go.mod index dbdc91a..ca92569 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ go 1.21 require ( github.com/hashicorp/terraform-plugin-docs v0.19.0 github.com/labd/contentful-go v0.5.3 + github.com/stretchr/testify v1.8.4 ) require ( @@ -21,6 +22,7 @@ require ( github.com/bgentry/speakeasy v0.1.0 // indirect github.com/bmatcuk/doublestar/v4 v4.6.1 // indirect github.com/cloudflare/circl v1.3.7 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect github.com/google/uuid v1.6.0 // indirect github.com/hashicorp/cli v1.1.6 // indirect github.com/hashicorp/hc-install v0.6.4 // indirect @@ -30,6 +32,7 @@ require ( github.com/huandu/xstrings v1.4.0 // indirect github.com/imdario/mergo v0.3.16 // indirect github.com/mattn/go-runewidth v0.0.15 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect github.com/posener/complete v1.2.3 // indirect github.com/rivo/uniseg v0.4.7 // indirect github.com/shopspring/decimal v1.4.0 // indirect From f218c8dc8ce2f048e925ec58d4df16b0b42fb998 Mon Sep 17 00:00:00 2001 From: Thomas De Meyer Date: Fri, 7 Jun 2024 11:18:12 +0200 Subject: [PATCH 183/192] feat: added changie files --- .changes/unreleased/Fixed-20240607-111741.yaml | 3 +++ .changes/unreleased/Fixed-20240607-111759.yaml | 3 +++ 2 files changed, 6 insertions(+) create mode 100644 .changes/unreleased/Fixed-20240607-111741.yaml create mode 100644 .changes/unreleased/Fixed-20240607-111759.yaml diff --git a/.changes/unreleased/Fixed-20240607-111741.yaml b/.changes/unreleased/Fixed-20240607-111741.yaml new file mode 100644 index 0000000..954675d --- /dev/null +++ b/.changes/unreleased/Fixed-20240607-111741.yaml @@ -0,0 +1,3 @@ +kind: Fixed +body: Added support for richtext +time: 2024-06-07T11:17:41.0428528+02:00 diff --git a/.changes/unreleased/Fixed-20240607-111759.yaml b/.changes/unreleased/Fixed-20240607-111759.yaml new file mode 100644 index 0000000..d1d0dea --- /dev/null +++ b/.changes/unreleased/Fixed-20240607-111759.yaml @@ -0,0 +1,3 @@ +kind: Fixed +body: Added better error handling +time: 2024-06-07T11:17:59.25875202+02:00 From 400403dcf4f7a82f458789b16b919c4c31352dea Mon Sep 17 00:00:00 2001 From: demeyerthom <8173199+demeyerthom@users.noreply.github.com> Date: Fri, 7 Jun 2024 14:40:15 +0000 Subject: [PATCH 184/192] Release v0.5.1 --- .changes/unreleased/Fixed-20240607-111741.yaml | 3 --- .changes/unreleased/Fixed-20240607-111759.yaml | 3 --- .changes/v0.5.1.md | 4 ++++ CHANGELOG.md | 5 +++++ 4 files changed, 9 insertions(+), 6 deletions(-) delete mode 100644 .changes/unreleased/Fixed-20240607-111741.yaml delete mode 100644 .changes/unreleased/Fixed-20240607-111759.yaml create mode 100644 .changes/v0.5.1.md diff --git a/.changes/unreleased/Fixed-20240607-111741.yaml b/.changes/unreleased/Fixed-20240607-111741.yaml deleted file mode 100644 index 954675d..0000000 --- a/.changes/unreleased/Fixed-20240607-111741.yaml +++ /dev/null @@ -1,3 +0,0 @@ -kind: Fixed -body: Added support for richtext -time: 2024-06-07T11:17:41.0428528+02:00 diff --git a/.changes/unreleased/Fixed-20240607-111759.yaml b/.changes/unreleased/Fixed-20240607-111759.yaml deleted file mode 100644 index d1d0dea..0000000 --- a/.changes/unreleased/Fixed-20240607-111759.yaml +++ /dev/null @@ -1,3 +0,0 @@ -kind: Fixed -body: Added better error handling -time: 2024-06-07T11:17:59.25875202+02:00 diff --git a/.changes/v0.5.1.md b/.changes/v0.5.1.md new file mode 100644 index 0000000..4355405 --- /dev/null +++ b/.changes/v0.5.1.md @@ -0,0 +1,4 @@ +## v0.5.1 - 2024-06-07 +### Fixed +* Added support for richtext +* Added better error handling diff --git a/CHANGELOG.md b/CHANGELOG.md index e21504f..57f2ab1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,11 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), and is generated by [Changie](https://github.com/miniscruff/changie). +## v0.5.1 - 2024-06-07 +### Fixed +* Added support for richtext +* Added better error handling + ## v0.5.0 - 2024-04-19 ### Added * Added option to set different base url for API From fb50aa4d8455fb498be9f650821f6687d2fc33e2 Mon Sep 17 00:00:00 2001 From: Thomas De Meyer Date: Fri, 21 Jun 2024 08:24:09 +0200 Subject: [PATCH 185/192] Revert "Release v0.5.1" --- .changes/unreleased/Fixed-20240607-111741.yaml | 3 +++ .changes/unreleased/Fixed-20240607-111759.yaml | 3 +++ .changes/v0.5.1.md | 4 ---- CHANGELOG.md | 5 ----- 4 files changed, 6 insertions(+), 9 deletions(-) create mode 100644 .changes/unreleased/Fixed-20240607-111741.yaml create mode 100644 .changes/unreleased/Fixed-20240607-111759.yaml delete mode 100644 .changes/v0.5.1.md diff --git a/.changes/unreleased/Fixed-20240607-111741.yaml b/.changes/unreleased/Fixed-20240607-111741.yaml new file mode 100644 index 0000000..954675d --- /dev/null +++ b/.changes/unreleased/Fixed-20240607-111741.yaml @@ -0,0 +1,3 @@ +kind: Fixed +body: Added support for richtext +time: 2024-06-07T11:17:41.0428528+02:00 diff --git a/.changes/unreleased/Fixed-20240607-111759.yaml b/.changes/unreleased/Fixed-20240607-111759.yaml new file mode 100644 index 0000000..d1d0dea --- /dev/null +++ b/.changes/unreleased/Fixed-20240607-111759.yaml @@ -0,0 +1,3 @@ +kind: Fixed +body: Added better error handling +time: 2024-06-07T11:17:59.25875202+02:00 diff --git a/.changes/v0.5.1.md b/.changes/v0.5.1.md deleted file mode 100644 index 4355405..0000000 --- a/.changes/v0.5.1.md +++ /dev/null @@ -1,4 +0,0 @@ -## v0.5.1 - 2024-06-07 -### Fixed -* Added support for richtext -* Added better error handling diff --git a/CHANGELOG.md b/CHANGELOG.md index 57f2ab1..e21504f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,11 +6,6 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), and is generated by [Changie](https://github.com/miniscruff/changie). -## v0.5.1 - 2024-06-07 -### Fixed -* Added support for richtext -* Added better error handling - ## v0.5.0 - 2024-04-19 ### Added * Added option to set different base url for API From c34316aca9ff396190257d6f32b8d00f6dc1de61 Mon Sep 17 00:00:00 2001 From: demeyerthom <8173199+demeyerthom@users.noreply.github.com> Date: Fri, 21 Jun 2024 06:29:11 +0000 Subject: [PATCH 186/192] Release v0.5.1 --- .changes/unreleased/Fixed-20240607-111741.yaml | 3 --- .changes/unreleased/Fixed-20240607-111759.yaml | 3 --- .changes/v0.5.1.md | 4 ++++ CHANGELOG.md | 5 +++++ 4 files changed, 9 insertions(+), 6 deletions(-) delete mode 100644 .changes/unreleased/Fixed-20240607-111741.yaml delete mode 100644 .changes/unreleased/Fixed-20240607-111759.yaml create mode 100644 .changes/v0.5.1.md diff --git a/.changes/unreleased/Fixed-20240607-111741.yaml b/.changes/unreleased/Fixed-20240607-111741.yaml deleted file mode 100644 index 954675d..0000000 --- a/.changes/unreleased/Fixed-20240607-111741.yaml +++ /dev/null @@ -1,3 +0,0 @@ -kind: Fixed -body: Added support for richtext -time: 2024-06-07T11:17:41.0428528+02:00 diff --git a/.changes/unreleased/Fixed-20240607-111759.yaml b/.changes/unreleased/Fixed-20240607-111759.yaml deleted file mode 100644 index d1d0dea..0000000 --- a/.changes/unreleased/Fixed-20240607-111759.yaml +++ /dev/null @@ -1,3 +0,0 @@ -kind: Fixed -body: Added better error handling -time: 2024-06-07T11:17:59.25875202+02:00 diff --git a/.changes/v0.5.1.md b/.changes/v0.5.1.md new file mode 100644 index 0000000..885386e --- /dev/null +++ b/.changes/v0.5.1.md @@ -0,0 +1,4 @@ +## v0.5.1 - 2024-06-21 +### Fixed +* Added support for richtext +* Added better error handling diff --git a/CHANGELOG.md b/CHANGELOG.md index e21504f..edf6921 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,11 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), and is generated by [Changie](https://github.com/miniscruff/changie). +## v0.5.1 - 2024-06-21 +### Fixed +* Added support for richtext +* Added better error handling + ## v0.5.0 - 2024-04-19 ### Added * Added option to set different base url for API From 63d2c468f4ef34bf2c704fee25fb92d5b71e1b84 Mon Sep 17 00:00:00 2001 From: Thomas De Meyer Date: Fri, 21 Jun 2024 08:29:15 +0200 Subject: [PATCH 187/192] Update release.yaml --- .github/workflows/release.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 819bef2..2a69e76 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -27,7 +27,7 @@ jobs: uses: goreleaser/goreleaser-action@v2 with: version: latest - args: release --rm-dist + args: release --clean env: GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From c793ec4a00670867d392b22e2f412e0337949262 Mon Sep 17 00:00:00 2001 From: demeyerthom <8173199+demeyerthom@users.noreply.github.com> Date: Fri, 21 Jun 2024 06:30:06 +0000 Subject: [PATCH 188/192] Release v0.5.1 --- .changes/unreleased/Fixed-20240607-111741.yaml | 3 --- .changes/unreleased/Fixed-20240607-111759.yaml | 3 --- .changes/v0.5.1.md | 4 ++++ CHANGELOG.md | 5 +++++ 4 files changed, 9 insertions(+), 6 deletions(-) delete mode 100644 .changes/unreleased/Fixed-20240607-111741.yaml delete mode 100644 .changes/unreleased/Fixed-20240607-111759.yaml create mode 100644 .changes/v0.5.1.md diff --git a/.changes/unreleased/Fixed-20240607-111741.yaml b/.changes/unreleased/Fixed-20240607-111741.yaml deleted file mode 100644 index 954675d..0000000 --- a/.changes/unreleased/Fixed-20240607-111741.yaml +++ /dev/null @@ -1,3 +0,0 @@ -kind: Fixed -body: Added support for richtext -time: 2024-06-07T11:17:41.0428528+02:00 diff --git a/.changes/unreleased/Fixed-20240607-111759.yaml b/.changes/unreleased/Fixed-20240607-111759.yaml deleted file mode 100644 index d1d0dea..0000000 --- a/.changes/unreleased/Fixed-20240607-111759.yaml +++ /dev/null @@ -1,3 +0,0 @@ -kind: Fixed -body: Added better error handling -time: 2024-06-07T11:17:59.25875202+02:00 diff --git a/.changes/v0.5.1.md b/.changes/v0.5.1.md new file mode 100644 index 0000000..885386e --- /dev/null +++ b/.changes/v0.5.1.md @@ -0,0 +1,4 @@ +## v0.5.1 - 2024-06-21 +### Fixed +* Added support for richtext +* Added better error handling diff --git a/CHANGELOG.md b/CHANGELOG.md index e21504f..edf6921 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,11 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), and is generated by [Changie](https://github.com/miniscruff/changie). +## v0.5.1 - 2024-06-21 +### Fixed +* Added support for richtext +* Added better error handling + ## v0.5.0 - 2024-04-19 ### Added * Added option to set different base url for API From e1f97e078324e51133b253803b922743ecab4302 Mon Sep 17 00:00:00 2001 From: "labd-project-manager[bot]" <141430439+labd-project-manager[bot]@users.noreply.github.com> Date: Fri, 2 Aug 2024 11:38:47 +0000 Subject: [PATCH 189/192] =?UTF-8?q?=F0=9F=94=84=20synced=20local=20'.githu?= =?UTF-8?q?b/'=20with=20remote=20'projects/go-terraform-provider/.github'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/dependabot.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml index 3e43501..44db557 100644 --- a/.github/dependabot.yaml +++ b/.github/dependabot.yaml @@ -3,7 +3,7 @@ updates: - package-ecosystem: "gomod" directory: "/" schedule: - interval: "weekly" + interval: "monthly" day: tuesday commit-message: prefix: "chore(deps)" @@ -15,7 +15,7 @@ updates: - package-ecosystem: "github-actions" directory: "/" schedule: - interval: "weekly" + interval: "monthly" day: tuesday commit-message: prefix: "chore(deps)" From d730f52af5dd79cc110f619bdbd6435b9e5f72c4 Mon Sep 17 00:00:00 2001 From: "labd-project-manager[bot]" <141430439+labd-project-manager[bot]@users.noreply.github.com> Date: Fri, 7 Mar 2025 14:51:26 +0000 Subject: [PATCH 190/192] =?UTF-8?q?=F0=9F=94=84=20synced=20local=20'.githu?= =?UTF-8?q?b/'=20with=20remote=20'projects/go-terraform-provider/.github'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/triage.yaml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/triage.yaml b/.github/workflows/triage.yaml index 6a30980..0dc162e 100644 --- a/.github/workflows/triage.yaml +++ b/.github/workflows/triage.yaml @@ -1,6 +1,9 @@ name: Triage on: + pull_request: + types: + - opened issues: types: - opened @@ -18,7 +21,7 @@ jobs: private-key: ${{ secrets.RD_APP_PRIVATE_KEY }} installation-id: ${{ secrets.RD_APP_INSTALLATION_ID }} - name: set to project board - uses: actions/add-to-project@v0.5.0 + uses: actions/add-to-project@v1.0.2 with: project-url: https://github.com/orgs/labd/projects/3 github-token: ${{ steps.get-app-token.outputs.app-token }} From a24047f3d6ec17e9967f0e0f806debc8167399c3 Mon Sep 17 00:00:00 2001 From: Michael van Tellingen Date: Mon, 24 Mar 2025 15:29:48 +0100 Subject: [PATCH 191/192] chore: use `labd/contentful-go` package The `contentful-go` package was updated with the flaconi changes --- Taskfile.yml | 12 ++++++++++++ contentful/errors.go | 2 +- contentful/errors_test.go | 2 +- contentful/provider.go | 6 +++--- contentful/resource_contentful_asset.go | 4 ++-- contentful/resource_contentful_asset_test.go | 2 +- contentful/resource_contentful_entry.go | 4 ++-- contentful/resource_contentful_entry_test.go | 2 +- contentful/resource_contentful_environment.go | 4 ++-- contentful/resource_contentful_environment_test.go | 4 ++-- contentful/resource_contentful_locale.go | 6 +++--- contentful/resource_contentful_locale_test.go | 4 ++-- contentful/resource_contentful_space.go | 4 ++-- contentful/resource_contentful_space_test.go | 2 +- contentful/resource_contentful_webhook.go | 4 ++-- contentful/resource_contentful_webhook_test.go | 4 ++-- go.mod | 4 +--- go.sum | 4 ++-- internal/acctest/client.go | 9 +++++---- internal/provider/provider.go | 6 +++--- internal/resources/api_key/model.go | 2 +- internal/resources/api_key/resource.go | 4 ++-- internal/resources/api_key/resource_test.go | 4 ++-- internal/resources/app_definition/model.go | 2 +- internal/resources/app_definition/resource.go | 6 +++--- internal/resources/app_definition/resource_test.go | 4 ++-- internal/resources/app_installation/model.go | 3 ++- internal/resources/app_installation/resource.go | 6 +++--- internal/resources/app_installation/resource_test.go | 4 ++-- internal/resources/contenttype/model.go | 4 ++-- internal/resources/contenttype/resource.go | 6 +++--- internal/resources/contenttype/resource_test.go | 6 +++--- internal/utils/container.go | 4 ++-- 33 files changed, 78 insertions(+), 66 deletions(-) diff --git a/Taskfile.yml b/Taskfile.yml index 5b36a74..0f43232 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -13,6 +13,18 @@ tasks: cmds: - go generate ./... + build-local: + cmds: + - go build -o terraform-provider-contentful_{{ .VERSION }} + - mkdir -p ~/.terraform.d/plugins/registry.terraform.io/labd/contentful/{{ .VERSION }}/{{ .PLATFORM }}/ + - mv terraform-provider-contentful_{{ .VERSION }} ~/.terraform.d/plugins/registry.terraform.io/labd/contentful/{{ .VERSION }}/{{ .PLATFORM }}/terraform-provider-contentful_v{{ .VERSION }} + - cmd: codesign --deep --force -s - ~/.terraform.d/plugins/registry.terraform.io/labd/contentful/{{ .VERSION }}/{{ .PLATFORM }}/terraform-provider-contentful_v{{ .VERSION }} + platforms: [ darwin ] + vars: + VERSION: 99.0.0 + PLATFORM: + sh: echo "$(go env GOOS)_$(go env GOARCH)" + coverage-html: cmds: - go test -race -coverprofile=coverage.txt -covermode=atomic -coverpkg=./... ./... diff --git a/contentful/errors.go b/contentful/errors.go index 28b7ffa..e12fa8d 100644 --- a/contentful/errors.go +++ b/contentful/errors.go @@ -5,8 +5,8 @@ import ( "fmt" "strings" - "github.com/flaconi/contentful-go/pkgs/common" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/labd/contentful-go/pkgs/common" ) func parseError(err error) diag.Diagnostics { diff --git a/contentful/errors_test.go b/contentful/errors_test.go index 26a2097..ffd2f79 100644 --- a/contentful/errors_test.go +++ b/contentful/errors_test.go @@ -4,8 +4,8 @@ import ( "fmt" "testing" - "github.com/flaconi/contentful-go/pkgs/common" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/labd/contentful-go/pkgs/common" "github.com/stretchr/testify/assert" ) diff --git a/contentful/provider.go b/contentful/provider.go index 7ae610a..e35955f 100644 --- a/contentful/provider.go +++ b/contentful/provider.go @@ -3,11 +3,11 @@ package contentful import ( "context" - contentful "github.com/flaconi/contentful-go" - client2 "github.com/flaconi/contentful-go/pkgs/client" - "github.com/flaconi/contentful-go/pkgs/util" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + contentful "github.com/labd/contentful-go" + client2 "github.com/labd/contentful-go/pkgs/client" + "github.com/labd/contentful-go/pkgs/util" "github.com/labd/terraform-provider-contentful/internal/utils" ) diff --git a/contentful/resource_contentful_asset.go b/contentful/resource_contentful_asset.go index b3a3d55..a7d63dd 100644 --- a/contentful/resource_contentful_asset.go +++ b/contentful/resource_contentful_asset.go @@ -5,9 +5,9 @@ import ( "fmt" "time" - "github.com/flaconi/contentful-go/pkgs/common" - "github.com/flaconi/contentful-go/pkgs/model" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/labd/contentful-go/pkgs/common" + "github.com/labd/contentful-go/pkgs/model" "github.com/labd/terraform-provider-contentful/internal/utils" ) diff --git a/contentful/resource_contentful_asset_test.go b/contentful/resource_contentful_asset_test.go index 04e7302..0de7c15 100644 --- a/contentful/resource_contentful_asset_test.go +++ b/contentful/resource_contentful_asset_test.go @@ -5,7 +5,7 @@ import ( "fmt" "testing" - "github.com/flaconi/contentful-go/pkgs/model" + "github.com/labd/contentful-go/pkgs/model" "github.com/labd/terraform-provider-contentful/internal/acctest" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" diff --git a/contentful/resource_contentful_entry.go b/contentful/resource_contentful_entry.go index cd7fc9c..973e7c4 100644 --- a/contentful/resource_contentful_entry.go +++ b/contentful/resource_contentful_entry.go @@ -4,10 +4,10 @@ import ( "context" "encoding/json" - "github.com/flaconi/contentful-go/pkgs/common" - "github.com/flaconi/contentful-go/pkgs/model" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/labd/contentful-go/pkgs/common" + "github.com/labd/contentful-go/pkgs/model" "github.com/labd/terraform-provider-contentful/internal/utils" ) diff --git a/contentful/resource_contentful_entry_test.go b/contentful/resource_contentful_entry_test.go index 68c1f76..7e4dc42 100644 --- a/contentful/resource_contentful_entry_test.go +++ b/contentful/resource_contentful_entry_test.go @@ -6,9 +6,9 @@ import ( "os" "testing" - "github.com/flaconi/contentful-go/pkgs/model" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/labd/contentful-go/pkgs/model" "github.com/labd/terraform-provider-contentful/internal/acctest" "github.com/stretchr/testify/assert" ) diff --git a/contentful/resource_contentful_environment.go b/contentful/resource_contentful_environment.go index 178caf0..f8f77f5 100644 --- a/contentful/resource_contentful_environment.go +++ b/contentful/resource_contentful_environment.go @@ -3,10 +3,10 @@ package contentful import ( "context" - "github.com/flaconi/contentful-go/pkgs/common" - "github.com/flaconi/contentful-go/pkgs/model" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/labd/contentful-go/pkgs/common" + "github.com/labd/contentful-go/pkgs/model" "github.com/labd/terraform-provider-contentful/internal/utils" ) diff --git a/contentful/resource_contentful_environment_test.go b/contentful/resource_contentful_environment_test.go index 578c9b4..1875cf3 100644 --- a/contentful/resource_contentful_environment_test.go +++ b/contentful/resource_contentful_environment_test.go @@ -6,8 +6,8 @@ import ( "os" "testing" - "github.com/flaconi/contentful-go/pkgs/common" - "github.com/flaconi/contentful-go/pkgs/model" + "github.com/labd/contentful-go/pkgs/common" + "github.com/labd/contentful-go/pkgs/model" "github.com/labd/terraform-provider-contentful/internal/acctest" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" diff --git a/contentful/resource_contentful_locale.go b/contentful/resource_contentful_locale.go index e341a87..237a922 100644 --- a/contentful/resource_contentful_locale.go +++ b/contentful/resource_contentful_locale.go @@ -6,11 +6,11 @@ import ( "fmt" "strings" - "github.com/flaconi/contentful-go/pkgs/common" - "github.com/flaconi/contentful-go/pkgs/model" - "github.com/flaconi/contentful-go/service/cma" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/labd/contentful-go/pkgs/common" + "github.com/labd/contentful-go/pkgs/model" + "github.com/labd/contentful-go/service/cma" "github.com/labd/terraform-provider-contentful/internal/utils" ) diff --git a/contentful/resource_contentful_locale_test.go b/contentful/resource_contentful_locale_test.go index b258fb5..0aac96b 100644 --- a/contentful/resource_contentful_locale_test.go +++ b/contentful/resource_contentful_locale_test.go @@ -7,8 +7,8 @@ import ( "os" "testing" - "github.com/flaconi/contentful-go/pkgs/common" - "github.com/flaconi/contentful-go/pkgs/model" + "github.com/labd/contentful-go/pkgs/common" + "github.com/labd/contentful-go/pkgs/model" "github.com/labd/terraform-provider-contentful/internal/acctest" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" diff --git a/contentful/resource_contentful_space.go b/contentful/resource_contentful_space.go index e54ca84..7ba0d8c 100644 --- a/contentful/resource_contentful_space.go +++ b/contentful/resource_contentful_space.go @@ -3,10 +3,10 @@ package contentful import ( "context" - "github.com/flaconi/contentful-go" - "github.com/flaconi/contentful-go/pkgs/common" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/labd/contentful-go" + "github.com/labd/contentful-go/pkgs/common" "github.com/labd/terraform-provider-contentful/internal/utils" ) diff --git a/contentful/resource_contentful_space_test.go b/contentful/resource_contentful_space_test.go index 9dfd83f..0f51d30 100644 --- a/contentful/resource_contentful_space_test.go +++ b/contentful/resource_contentful_space_test.go @@ -4,9 +4,9 @@ import ( "fmt" "testing" - contentful "github.com/flaconi/contentful-go" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + contentful "github.com/labd/contentful-go" ) func TestAccContentfulSpace_Basic(t *testing.T) { diff --git a/contentful/resource_contentful_webhook.go b/contentful/resource_contentful_webhook.go index 131e82a..f0bad2a 100644 --- a/contentful/resource_contentful_webhook.go +++ b/contentful/resource_contentful_webhook.go @@ -3,10 +3,10 @@ package contentful import ( "context" - "github.com/flaconi/contentful-go" - "github.com/flaconi/contentful-go/pkgs/common" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/labd/contentful-go" + "github.com/labd/contentful-go/pkgs/common" "github.com/labd/terraform-provider-contentful/internal/utils" ) diff --git a/contentful/resource_contentful_webhook_test.go b/contentful/resource_contentful_webhook_test.go index ada9171..9baac31 100644 --- a/contentful/resource_contentful_webhook_test.go +++ b/contentful/resource_contentful_webhook_test.go @@ -4,12 +4,12 @@ import ( "fmt" "testing" - "github.com/flaconi/contentful-go/pkgs/common" + "github.com/labd/contentful-go/pkgs/common" "github.com/labd/terraform-provider-contentful/internal/acctest" - contentful "github.com/flaconi/contentful-go" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + contentful "github.com/labd/contentful-go" ) func TestAccContentfulWebhook_Basic(t *testing.T) { diff --git a/go.mod b/go.mod index a84a3ec..76929bc 100644 --- a/go.mod +++ b/go.mod @@ -4,17 +4,15 @@ go 1.23.0 toolchain go1.23.7 -//replace github.com/flaconi/contentful-go => ../contentful-go - require ( github.com/elliotchance/pie/v2 v2.9.1 - github.com/flaconi/contentful-go v0.5.3-0.20240307133521-ac9bdf1c97f2 github.com/hashicorp/terraform-plugin-docs v0.19.0 github.com/hashicorp/terraform-plugin-framework v1.14.1 github.com/hashicorp/terraform-plugin-framework-jsontypes v0.2.0 github.com/hashicorp/terraform-plugin-framework-validators v0.17.0 github.com/hashicorp/terraform-plugin-mux v0.18.0 github.com/hashicorp/terraform-plugin-testing v1.12.0 + github.com/labd/contentful-go v0.5.4-0.20250324140149-2fdab88b69c2 github.com/stretchr/testify v1.9.0 ) diff --git a/go.sum b/go.sum index 6fca630..ade1caa 100644 --- a/go.sum +++ b/go.sum @@ -42,8 +42,6 @@ github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FM github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= -github.com/flaconi/contentful-go v0.5.3-0.20240307133521-ac9bdf1c97f2 h1:h2Q7lCAU/DP3yFz7GRRKSKKoHyepnyEwll1pg8x3BS8= -github.com/flaconi/contentful-go v0.5.3-0.20240307133521-ac9bdf1c97f2/go.mod h1:j6xpYF+19owGCT9j6Wx5XaM8Gub9s5UcXUMw4B4teZY= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= @@ -151,6 +149,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/labd/contentful-go v0.5.4-0.20250324140149-2fdab88b69c2 h1:Tz4faVF5rrjzHtOo7bR2fhEpooCXCbwFE42zyn6IFpQ= +github.com/labd/contentful-go v0.5.4-0.20250324140149-2fdab88b69c2/go.mod h1:SrC2m8PCbpFiMkVJjODPI6e/8Nne6/Q27sxsXOiXs5A= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= diff --git a/internal/acctest/client.go b/internal/acctest/client.go index 2c05568..4d0b0ac 100644 --- a/internal/acctest/client.go +++ b/internal/acctest/client.go @@ -1,11 +1,12 @@ package acctest import ( - "github.com/flaconi/contentful-go" - client2 "github.com/flaconi/contentful-go/pkgs/client" - "github.com/flaconi/contentful-go/pkgs/util" - "github.com/flaconi/contentful-go/service/cma" "os" + + "github.com/labd/contentful-go" + client2 "github.com/labd/contentful-go/pkgs/client" + "github.com/labd/contentful-go/pkgs/util" + "github.com/labd/contentful-go/service/cma" ) func GetClient() *contentful.Client { diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 9161227..abe2708 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -4,14 +4,14 @@ import ( "context" "os" - "github.com/flaconi/contentful-go" - client2 "github.com/flaconi/contentful-go/pkgs/client" - "github.com/flaconi/contentful-go/pkgs/util" "github.com/hashicorp/terraform-plugin-framework/datasource" "github.com/hashicorp/terraform-plugin-framework/provider" "github.com/hashicorp/terraform-plugin-framework/provider/schema" "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/labd/contentful-go" + client2 "github.com/labd/contentful-go/pkgs/client" + "github.com/labd/contentful-go/pkgs/util" "github.com/labd/terraform-provider-contentful/internal/resources/api_key" "github.com/labd/terraform-provider-contentful/internal/resources/app_definition" diff --git a/internal/resources/api_key/model.go b/internal/resources/api_key/model.go index 16d76da..f652107 100644 --- a/internal/resources/api_key/model.go +++ b/internal/resources/api_key/model.go @@ -2,8 +2,8 @@ package api_key import ( "github.com/elliotchance/pie/v2" - "github.com/flaconi/contentful-go/pkgs/model" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/labd/contentful-go/pkgs/model" ) // ApiKey is the main resource schema data diff --git a/internal/resources/api_key/resource.go b/internal/resources/api_key/resource.go index bcd724e..3db14ab 100644 --- a/internal/resources/api_key/resource.go +++ b/internal/resources/api_key/resource.go @@ -5,8 +5,6 @@ import ( "fmt" "strings" - "github.com/flaconi/contentful-go/pkgs/model" - "github.com/flaconi/contentful-go/service/cma" "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/resource" @@ -15,6 +13,8 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/tfsdk" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/labd/contentful-go/pkgs/model" + "github.com/labd/contentful-go/service/cma" "github.com/labd/terraform-provider-contentful/internal/custommodifier" "github.com/labd/terraform-provider-contentful/internal/utils" ) diff --git a/internal/resources/api_key/resource_test.go b/internal/resources/api_key/resource_test.go index deecb9e..596c7bd 100644 --- a/internal/resources/api_key/resource_test.go +++ b/internal/resources/api_key/resource_test.go @@ -8,13 +8,13 @@ import ( "regexp" "testing" - "github.com/flaconi/contentful-go/pkgs/common" - "github.com/flaconi/contentful-go/pkgs/model" "github.com/hashicorp/terraform-plugin-framework/providerserver" "github.com/hashicorp/terraform-plugin-go/tfprotov6" hashicor_acctest "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" + "github.com/labd/contentful-go/pkgs/common" + "github.com/labd/contentful-go/pkgs/model" "github.com/labd/terraform-provider-contentful/internal/acctest" "github.com/labd/terraform-provider-contentful/internal/provider" "github.com/labd/terraform-provider-contentful/internal/utils" diff --git a/internal/resources/app_definition/model.go b/internal/resources/app_definition/model.go index 6012f45..cd0f45e 100644 --- a/internal/resources/app_definition/model.go +++ b/internal/resources/app_definition/model.go @@ -2,8 +2,8 @@ package app_definition import ( "github.com/elliotchance/pie/v2" - "github.com/flaconi/contentful-go/pkgs/model" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/labd/contentful-go/pkgs/model" "github.com/labd/terraform-provider-contentful/internal/utils" ) diff --git a/internal/resources/app_definition/resource.go b/internal/resources/app_definition/resource.go index 078a408..f253ae5 100644 --- a/internal/resources/app_definition/resource.go +++ b/internal/resources/app_definition/resource.go @@ -4,9 +4,6 @@ import ( "context" _ "embed" - "github.com/flaconi/contentful-go" - "github.com/flaconi/contentful-go/pkgs/model" - "github.com/flaconi/contentful-go/service/cma" "github.com/hashicorp/terraform-plugin-framework-validators/listvalidator" "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" "github.com/hashicorp/terraform-plugin-framework/diag" @@ -18,6 +15,9 @@ import ( "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/tfsdk" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/labd/contentful-go" + "github.com/labd/contentful-go/pkgs/model" + "github.com/labd/contentful-go/service/cma" "github.com/labd/terraform-provider-contentful/internal/custommodifier" "github.com/labd/terraform-provider-contentful/internal/customvalidator" "github.com/labd/terraform-provider-contentful/internal/utils" diff --git a/internal/resources/app_definition/resource_test.go b/internal/resources/app_definition/resource_test.go index 2a33c4d..84c2803 100644 --- a/internal/resources/app_definition/resource_test.go +++ b/internal/resources/app_definition/resource_test.go @@ -8,12 +8,12 @@ import ( "regexp" "testing" - "github.com/flaconi/contentful-go/pkgs/common" - "github.com/flaconi/contentful-go/pkgs/model" "github.com/hashicorp/terraform-plugin-framework/providerserver" "github.com/hashicorp/terraform-plugin-go/tfprotov6" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" + "github.com/labd/contentful-go/pkgs/common" + "github.com/labd/contentful-go/pkgs/model" "github.com/labd/terraform-provider-contentful/internal/acctest" "github.com/labd/terraform-provider-contentful/internal/provider" "github.com/labd/terraform-provider-contentful/internal/utils" diff --git a/internal/resources/app_installation/model.go b/internal/resources/app_installation/model.go index 0026bd2..1e544e7 100644 --- a/internal/resources/app_installation/model.go +++ b/internal/resources/app_installation/model.go @@ -2,10 +2,11 @@ package app_installation import ( "encoding/json" + "github.com/elliotchance/pie/v2" - "github.com/flaconi/contentful-go/pkgs/model" "github.com/hashicorp/terraform-plugin-framework-jsontypes/jsontypes" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/labd/contentful-go/pkgs/model" ) // AppInstallation is the main resource schema data diff --git a/internal/resources/app_installation/resource.go b/internal/resources/app_installation/resource.go index c7642b3..ca7ca7d 100644 --- a/internal/resources/app_installation/resource.go +++ b/internal/resources/app_installation/resource.go @@ -7,9 +7,6 @@ import ( "fmt" "strings" - "github.com/flaconi/contentful-go/pkgs/common" - "github.com/flaconi/contentful-go/pkgs/model" - "github.com/flaconi/contentful-go/service/cma" "github.com/hashicorp/terraform-plugin-framework-jsontypes/jsontypes" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/resource" @@ -18,6 +15,9 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/tfsdk" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/labd/contentful-go/pkgs/common" + "github.com/labd/contentful-go/pkgs/model" + "github.com/labd/contentful-go/service/cma" "github.com/labd/terraform-provider-contentful/internal/utils" ) diff --git a/internal/resources/app_installation/resource_test.go b/internal/resources/app_installation/resource_test.go index dd2f62f..6615e12 100644 --- a/internal/resources/app_installation/resource_test.go +++ b/internal/resources/app_installation/resource_test.go @@ -7,12 +7,12 @@ import ( "os" "testing" - "github.com/flaconi/contentful-go/pkgs/common" - "github.com/flaconi/contentful-go/pkgs/model" "github.com/hashicorp/terraform-plugin-framework/providerserver" "github.com/hashicorp/terraform-plugin-go/tfprotov6" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" + "github.com/labd/contentful-go/pkgs/common" + "github.com/labd/contentful-go/pkgs/model" "github.com/labd/terraform-provider-contentful/internal/acctest" "github.com/labd/terraform-provider-contentful/internal/provider" "github.com/labd/terraform-provider-contentful/internal/utils" diff --git a/internal/resources/contenttype/model.go b/internal/resources/contenttype/model.go index a3282bf..66a8213 100644 --- a/internal/resources/contenttype/model.go +++ b/internal/resources/contenttype/model.go @@ -6,11 +6,11 @@ import ( "reflect" "github.com/elliotchance/pie/v2" - "github.com/flaconi/contentful-go" - "github.com/flaconi/contentful-go/pkgs/model" "github.com/hashicorp/terraform-plugin-framework-jsontypes/jsontypes" "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/labd/contentful-go" + "github.com/labd/contentful-go/pkgs/model" "github.com/labd/terraform-provider-contentful/internal/utils" ) diff --git a/internal/resources/contenttype/resource.go b/internal/resources/contenttype/resource.go index abcbea2..363df68 100644 --- a/internal/resources/contenttype/resource.go +++ b/internal/resources/contenttype/resource.go @@ -7,9 +7,6 @@ import ( "strings" "github.com/elliotchance/pie/v2" - "github.com/flaconi/contentful-go" - "github.com/flaconi/contentful-go/pkgs/model" - "github.com/flaconi/contentful-go/service/cma" "github.com/hashicorp/terraform-plugin-framework-jsontypes/jsontypes" "github.com/hashicorp/terraform-plugin-framework-validators/listvalidator" "github.com/hashicorp/terraform-plugin-framework-validators/objectvalidator" @@ -24,6 +21,9 @@ import ( "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/tfsdk" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/labd/contentful-go" + "github.com/labd/contentful-go/pkgs/model" + "github.com/labd/contentful-go/service/cma" "github.com/labd/terraform-provider-contentful/internal/custommodifier" "github.com/labd/terraform-provider-contentful/internal/customvalidator" "github.com/labd/terraform-provider-contentful/internal/utils" diff --git a/internal/resources/contenttype/resource_test.go b/internal/resources/contenttype/resource_test.go index c9e5ad4..a9f78e8 100644 --- a/internal/resources/contenttype/resource_test.go +++ b/internal/resources/contenttype/resource_test.go @@ -7,13 +7,13 @@ import ( "os" "regexp" - "github.com/flaconi/contentful-go" - "github.com/flaconi/contentful-go/pkgs/common" - "github.com/flaconi/contentful-go/pkgs/model" "github.com/hashicorp/terraform-plugin-framework/providerserver" "github.com/hashicorp/terraform-plugin-go/tfprotov6" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/labd/contentful-go" + "github.com/labd/contentful-go/pkgs/common" + "github.com/labd/contentful-go/pkgs/model" "github.com/labd/terraform-provider-contentful/internal/acctest" "github.com/labd/terraform-provider-contentful/internal/provider" "github.com/labd/terraform-provider-contentful/internal/utils" diff --git a/internal/utils/container.go b/internal/utils/container.go index 748b82b..d09b2ba 100644 --- a/internal/utils/container.go +++ b/internal/utils/container.go @@ -1,8 +1,8 @@ package utils import ( - "github.com/flaconi/contentful-go" - "github.com/flaconi/contentful-go/service/cma" + "github.com/labd/contentful-go" + "github.com/labd/contentful-go/service/cma" ) type ProviderData struct { From 2e259284afe785cf1796bf5e7dfca6666a16accb Mon Sep 17 00:00:00 2001 From: Michael van Tellingen Date: Mon, 24 Mar 2025 22:46:06 +0100 Subject: [PATCH 192/192] refactor: initial steps with openapi generated sdk This adds a reverse-engineered openapi spec to generate the contentful sdk. It updates the code to use this sdk --- .gitignore | 3 + Taskfile.yml | 1 + contentful/provider.go | 41 +- contentful/resource_contentful_entry.go | 156 +- contentful/resource_contentful_environment.go | 82 +- contentful/resource_contentful_locale.go | 143 +- contentful/resource_contentful_space.go | 83 +- contentful/resource_contentful_webhook.go | 89 +- go.mod | 18 +- go.sum | 122 +- internal/provider/provider.go | 1 - internal/resources/app_definition/resource.go | 3 +- internal/resources/contenttype/resource.go | 3 +- internal/sdk/main.gen.go | 5575 +++++++++++++++++ internal/utils/container.go | 5 +- internal/utils/http_debug.go | 63 + internal/utils/types.go | 4 + oapi-config.yaml | 7 + openapi.yaml | 1307 ++++ tools.go | 1 + 20 files changed, 7481 insertions(+), 226 deletions(-) create mode 100644 internal/sdk/main.gen.go create mode 100644 internal/utils/http_debug.go create mode 100644 oapi-config.yaml create mode 100644 openapi.yaml diff --git a/.gitignore b/.gitignore index 897eeb6..92303c2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,8 @@ terraform-provider-contentful .envrc +.terraform* +NOTES.md +main.tf *.backup /dist/* diff --git a/Taskfile.yml b/Taskfile.yml index 0f43232..8195122 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -11,6 +11,7 @@ tasks: generate: cmds: + - go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=oapi-config.yaml ./openapi.yaml - go generate ./... build-local: diff --git a/contentful/provider.go b/contentful/provider.go index e35955f..4911b70 100644 --- a/contentful/provider.go +++ b/contentful/provider.go @@ -2,13 +2,13 @@ package contentful import ( "context" + "net/http" + "github.com/deepmap/oapi-codegen/pkg/securityprovider" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - contentful "github.com/labd/contentful-go" - client2 "github.com/labd/contentful-go/pkgs/client" - "github.com/labd/contentful-go/pkgs/util" + "github.com/labd/terraform-provider-contentful/internal/sdk" "github.com/labd/terraform-provider-contentful/internal/utils" ) @@ -62,31 +62,36 @@ func Provider() func() *schema.Provider { // providerConfigure sets the configuration for the Terraform Provider func providerConfigure(_ context.Context, d *schema.ResourceData) (interface{}, diag.Diagnostics) { - cma := contentful.NewCMA(d.Get("cma_token").(string)) - cma.SetOrganization(d.Get("organization_id").(string)) - cma.BaseURL = d.Get("base_url").(string) - cma.SetEnvironment(d.Get("environment").(string)) + baseURL := d.Get("base_url").(string) + token := d.Get("cma_token").(string) - debug := false + authProvider, err := securityprovider.NewSecurityProviderBearerToken(token) + if err != nil { + return nil, diag.Errorf("Unable to Create Storyblok API Client", err.Error()) + } + + httpClient := &http.Client{ + Transport: http.DefaultTransport, + } + httpClient.Transport = utils.NewDebugTransport(httpClient.Transport) - if logBoolean != "" { - cma.Debug = true - debug = true + setVersionHeader := func(ctx context.Context, req *http.Request) error { + req.Header.Set("Content-Type", "application/vnd.contentful.management.v1+json") + return nil } - client, err := contentful.NewCMAV2(client2.ClientConfig{ - Debug: debug, - UserAgent: util.ToPointer("terraform-provider-contentful"), - Token: d.Get("cma_token").(string), - }) + client, err := sdk.NewClientWithResponses( + baseURL, + sdk.WithHTTPClient(httpClient), + sdk.WithRequestEditorFn(setVersionHeader), + sdk.WithRequestEditorFn(authProvider.Intercept)) if err != nil { return nil, diag.FromErr(err) } data := utils.ProviderData{ - Client: cma, - CMAClient: client, + Client: client, OrganizationId: d.Get("organization_id").(string), } diff --git a/contentful/resource_contentful_entry.go b/contentful/resource_contentful_entry.go index 973e7c4..f185b5e 100644 --- a/contentful/resource_contentful_entry.go +++ b/contentful/resource_contentful_entry.go @@ -3,12 +3,12 @@ package contentful import ( "context" "encoding/json" + "fmt" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/labd/contentful-go/pkgs/common" - "github.com/labd/contentful-go/pkgs/model" + "github.com/labd/terraform-provider-contentful/internal/sdk" "github.com/labd/terraform-provider-contentful/internal/utils" ) @@ -75,8 +75,10 @@ func resourceContentfulEntry() *schema.Resource { } } -func resourceCreateEntry(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - client := m.(utils.ProviderData).CMAClient +func resourceCreateEntry(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + client := m.(utils.ProviderData).Client + spaceID := d.Get("space_id").(string) + environmentID := d.Get("environment").(string) fieldProperties := map[string]interface{}{} rawField := d.Get("field").([]interface{}) @@ -86,114 +88,156 @@ func resourceCreateEntry(_ context.Context, d *schema.ResourceData, m interface{ fieldProperties[field["id"].(string)].(map[string]interface{})[field["locale"].(string)] = parseContentValue(field["content"].(string)) } - entry := &model.Entry{ - Fields: fieldProperties, - Sys: &model.PublishSys{ - EnvironmentSys: model.EnvironmentSys{ - SpaceSys: model.SpaceSys{ - CreatedSys: model.CreatedSys{ - BaseSys: model.BaseSys{ - ID: d.Get("entry_id").(string), - }, - }, - }, - }, - }, + body := sdk.EntryCreate{ + Fields: &fieldProperties, } - err := client.WithSpaceId(d.Get("space_id").(string)).WithEnvironment(d.Get("environment").(string)).Entries().Upsert(context.Background(), d.Get("contenttype_id").(string), entry) + resp, err := client.CreateEntryWithResponse(ctx, spaceID, environmentID, nil, body) if err != nil { return parseError(err) } + if resp.StatusCode() != 201 { + return diag.Errorf("Failed to create entry") + } + + entry := resp.JSON201 if err := setEntryProperties(d, entry); err != nil { return parseError(err) } - d.SetId(entry.Sys.ID) + d.SetId(*entry.Sys.Id) - if err := setEntryState(d, m); err != nil { + if err := setEntryState(ctx, d, m); err != nil { return parseError(err) } return parseError(err) } -func resourceUpdateEntry(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - client := m.(utils.ProviderData).CMAClient +func resourceUpdateEntry(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + client := m.(utils.ProviderData).Client spaceID := d.Get("space_id").(string) + environmentID := d.Get("environment").(string) entryID := d.Id() - entryClient := client.WithSpaceId(spaceID).WithEnvironment(d.Get("environment").(string)).Entries() - - entry, err := entryClient.Get(context.Background(), entryID) - if err != nil { - return parseError(err) + fieldProperties := map[string]any{} + rawField := d.Get("field").([]any) + for i := 0; i < len(rawField); i++ { + field := rawField[i].(map[string]any) + fieldProperties[field["id"].(string)] = map[string]any{} + fieldProperties[field["id"].(string)].(map[string]any)[field["locale"].(string)] = parseContentValue(field["content"].(string)) } - fieldProperties := map[string]interface{}{} - rawField := d.Get("field").([]interface{}) - for i := 0; i < len(rawField); i++ { - field := rawField[i].(map[string]interface{}) - fieldProperties[field["id"].(string)] = map[string]interface{}{} - fieldProperties[field["id"].(string)].(map[string]interface{})[field["locale"].(string)] = parseContentValue(field["content"].(string)) + body := sdk.EntryUpdate{ + Fields: &fieldProperties, } - entry.Fields = fieldProperties + params := &sdk.UpdateEntryParams{ + XContentfulVersion: d.Get("version").(int), + } - err = entryClient.Upsert(context.Background(), d.Get("contenttype_id").(string), entry) + resp, err := client.UpdateEntryWithResponse(ctx, spaceID, environmentID, entryID, params, body) if err != nil { return parseError(err) } - d.SetId(entry.Sys.ID) + if resp.StatusCode() != 200 { + return diag.Errorf("Failed to update entry") + } + + entry := resp.JSON200 + d.SetId(*entry.Sys.Id) if err := setEntryProperties(d, entry); err != nil { return parseError(err) } - if err := setEntryState(d, m); err != nil { + if err := setEntryState(ctx, d, m); err != nil { return parseError(err) } return nil } -func setEntryState(d *schema.ResourceData, m interface{}) (err error) { - client := m.(utils.ProviderData).CMAClient +func setEntryState(ctx context.Context, d *schema.ResourceData, m interface{}) (err error) { + client := m.(utils.ProviderData).Client spaceID := d.Get("space_id").(string) entryID := d.Id() + environmentID := d.Get("environment").(string) - entryClient := client.WithSpaceId(spaceID).WithEnvironment(d.Get("environment").(string)).Entries() + published := d.Get("published").(bool) + archived := d.Get("archived").(bool) - entry, _ := entryClient.Get(context.Background(), entryID) + resp, err := client.GetEntryWithResponse(ctx, spaceID, environmentID, entryID) + if err != nil { + return err + } + + if resp.StatusCode() != 200 { + return fmt.Errorf("Failed to get entry") + } - if d.Get("published").(bool) && entry.Sys.PublishedAt == "" { - err = entryClient.Publish(context.Background(), entry) - } else if !d.Get("published").(bool) && entry.Sys.PublishedAt != "" { - err = entryClient.Unpublish(context.Background(), entry) + entry := resp.JSON200 + + if published && entry.Sys.PublishedAt == nil { + resp, err := client.PublishEntryWithResponse(ctx, spaceID, environmentID, entryID) + if err != nil { + return err + } + if resp.StatusCode() != 200 { + return fmt.Errorf("Failed to publish entry") + } + } else if !published && entry.Sys.PublishedAt != nil { + resp, err := client.UnpublishEntryWithResponse(ctx, spaceID, environmentID, entryID) + if err != nil { + return err + } + if resp.StatusCode() != 200 { + return fmt.Errorf("Failed to unpublish entry") + } } - if d.Get("archived").(bool) && entry.Sys.ArchivedAt == "" { - err = entryClient.Archive(context.Background(), entry) - } else if !d.Get("archived").(bool) && entry.Sys.ArchivedAt != "" { - err = entryClient.Unarchive(context.Background(), entry) + if archived && entry.Sys.ArchivedAt == nil { + resp, err := client.ArchiveEntryWithResponse(ctx, spaceID, environmentID, entryID) + if err != nil { + return err + } + if resp.StatusCode() != 200 { + return fmt.Errorf("Failed to archive entry") + } + + } else if !archived && entry.Sys.ArchivedAt != nil { + resp, err := client.UnarchiveEntryWithResponse(ctx, spaceID, environmentID, entryID) + if err != nil { + return err + } + if resp.StatusCode() != 200 { + return fmt.Errorf("Failed to unarchive entry") + } } return err } -func resourceReadEntry(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - client := m.(utils.ProviderData).CMAClient +func resourceReadEntry(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + client := m.(utils.ProviderData).Client spaceID := d.Get("space_id").(string) entryID := d.Id() + environmentID := d.Get("environment").(string) + + resp, err := client.GetEntryWithResponse(ctx, spaceID, environmentID, entryID) + + if err != nil { + return parseError(err) + } - entry, err := client.WithSpaceId(spaceID).WithEnvironment(d.Get("environment").(string)).Entries().Get(context.Background(), entryID) - if _, ok := err.(common.NotFoundError); ok { + if resp.StatusCode() != 200 { d.SetId("") return nil } + entry := resp.JSON200 err = setEntryProperties(d, entry) if err != nil { return parseError(err) @@ -221,8 +265,8 @@ func resourceDeleteEntry(_ context.Context, d *schema.ResourceData, m interface{ return nil } -func setEntryProperties(d *schema.ResourceData, entry *model.Entry) (err error) { - if err = d.Set("space_id", entry.Sys.Space.Sys.ID); err != nil { +func setEntryProperties(d *schema.ResourceData, entry *sdk.Entry) (err error) { + if err = d.Set("space_id", entry.Sys.Space.Sys.Id); err != nil { return err } @@ -230,7 +274,7 @@ func setEntryProperties(d *schema.ResourceData, entry *model.Entry) (err error) return err } - if err = d.Set("contenttype_id", entry.Sys.ContentType.Sys.ID); err != nil { + if err = d.Set("contenttype_id", entry.Sys.ContentType.Sys.Id); err != nil { return err } diff --git a/contentful/resource_contentful_environment.go b/contentful/resource_contentful_environment.go index f8f77f5..c525ae2 100644 --- a/contentful/resource_contentful_environment.go +++ b/contentful/resource_contentful_environment.go @@ -5,9 +5,8 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/labd/contentful-go/pkgs/common" - "github.com/labd/contentful-go/pkgs/model" + "github.com/labd/terraform-provider-contentful/internal/sdk" "github.com/labd/terraform-provider-contentful/internal/utils" ) @@ -18,6 +17,9 @@ func resourceContentfulEnvironment() *schema.Resource { ReadContext: resourceReadEnvironment, UpdateContext: resourceUpdateEnvironment, DeleteContext: resourceDeleteEnvironment, + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, Schema: map[string]*schema.Schema{ "version": { @@ -36,66 +38,85 @@ func resourceContentfulEnvironment() *schema.Resource { } } -func resourceCreateEnvironment(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - client := m.(utils.ProviderData).CMAClient +func resourceCreateEnvironment(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + client := m.(utils.ProviderData).Client + spaceID := d.Get("space_id").(string) - environment := &model.Environment{ + body := sdk.EnvironmentCreate{ Name: d.Get("name").(string), } - err := client.WithSpaceId(spaceID).Environments().Upsert(context.Background(), environment, nil) + resp, err := client.CreateEnvironmentWithResponse(ctx, spaceID, body) if err != nil { return parseError(err) } + if resp.StatusCode() != 201 { + return diag.Errorf("Failed to create environment") + } + + environment := resp.JSON201 if err := setEnvironmentProperties(d, environment); err != nil { return parseError(err) } - d.SetId(environment.Name) + d.SetId(*environment.Sys.Id) return nil } -func resourceUpdateEnvironment(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - client := m.(utils.ProviderData).CMAClient +func resourceUpdateEnvironment(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + client := m.(utils.ProviderData).Client spaceID := d.Get("space_id").(string) environmentID := d.Id() - envClient := client.WithSpaceId(spaceID).Environments() - - environment, err := envClient.Get(context.Background(), environmentID) - if err != nil { - return parseError(err) + body := sdk.EnvironmentUpdate{ + Name: d.Get("name").(string), } - environment.Name = d.Get("name").(string) + params := &sdk.UpdateEnvironmentParams{ + XContentfulVersion: d.Get("version").(int), + } - err = envClient.Upsert(context.Background(), environment, nil) + resp, err := client.UpdateEnvironmentWithResponse(ctx, spaceID, environmentID, params, body) if err != nil { return parseError(err) } + if resp.StatusCode() != 200 { + return diag.Errorf("Failed to update environment") + } + + environment := resp.JSON200 if err := setEnvironmentProperties(d, environment); err != nil { return parseError(err) } - d.SetId(environment.Sys.ID) + d.SetId(*environment.Sys.Id) return nil } -func resourceReadEnvironment(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - client := m.(utils.ProviderData).CMAClient +func resourceReadEnvironment(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + client := m.(utils.ProviderData).Client spaceID := d.Get("space_id").(string) environmentID := d.Id() - environment, err := client.WithSpaceId(spaceID).Environments().Get(context.Background(), environmentID) - if _, ok := err.(common.NotFoundError); ok { + resp, err := client.GetEnvironmentWithResponse(ctx, spaceID, environmentID) + if err != nil { + return parseError(err) + } + + if resp.StatusCode() == 404 { d.SetId("") return nil } + if resp.StatusCode() != 200 { + return diag.Errorf("Failed to read environment") + } + + environment := resp.JSON200 err = setEnvironmentProperties(d, environment) if err != nil { return parseError(err) @@ -104,28 +125,29 @@ func resourceReadEnvironment(_ context.Context, d *schema.ResourceData, m interf return nil } -func resourceDeleteEnvironment(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - client := m.(utils.ProviderData).CMAClient +func resourceDeleteEnvironment(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + client := m.(utils.ProviderData).Client spaceID := d.Get("space_id").(string) environmentID := d.Id() - envClient := client.WithSpaceId(spaceID).Environments() + params := &sdk.DeleteEnvironmentParams{ + XContentfulVersion: d.Get("version").(int), + } - environment, err := envClient.Get(context.Background(), environmentID) + resp, err := client.DeleteEnvironmentWithResponse(ctx, spaceID, environmentID, params) if err != nil { return parseError(err) } - err = envClient.Delete(context.Background(), environment) - if err != nil { - return parseError(err) + if resp.StatusCode() != 204 { + return diag.Errorf("Failed to delete environment") } return nil } -func setEnvironmentProperties(d *schema.ResourceData, environment *model.Environment) error { - if err := d.Set("space_id", environment.Sys.Space.Sys.ID); err != nil { +func setEnvironmentProperties(d *schema.ResourceData, environment *sdk.Environment) error { + if err := d.Set("space_id", environment.Sys.Space.Sys.Id); err != nil { return err } diff --git a/contentful/resource_contentful_locale.go b/contentful/resource_contentful_locale.go index 237a922..62b3f65 100644 --- a/contentful/resource_contentful_locale.go +++ b/contentful/resource_contentful_locale.go @@ -2,16 +2,13 @@ package contentful import ( "context" - "errors" "fmt" "strings" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/labd/contentful-go/pkgs/common" - "github.com/labd/contentful-go/pkgs/model" - "github.com/labd/contentful-go/service/cma" + "github.com/labd/terraform-provider-contentful/internal/sdk" "github.com/labd/terraform-provider-contentful/internal/utils" ) @@ -100,59 +97,61 @@ func resourceContentfulLocale() *schema.Resource { } } -func resourceCreateLocale(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - client := m.(utils.ProviderData).CMAClient +func resourceCreateLocale(ctx context.Context, d *schema.ResourceData, m any) diag.Diagnostics { + client := m.(utils.ProviderData).Client spaceID := d.Get("space_id").(string) - localesClient := client.WithSpaceId(spaceID).WithEnvironment(d.Get("environment").(string)).Locales() - var err error - - locale := &model.Locale{ - Name: d.Get("name").(string), - Code: d.Get("code").(string), - FallbackCode: nil, - Optional: d.Get("optional").(bool), - CDA: d.Get("cda").(bool), - CMA: d.Get("cma").(bool), + environmentID := d.Get("environment").(string) + + body := sdk.LocaleCreate{ + Name: d.Get("name").(string), + Code: d.Get("code").(string), + FallbackCode: nil, + Optional: utils.Pointer(d.Get("optional").(bool)), + ContentDeliveryApi: utils.Pointer(d.Get("cda").(bool)), + ContentManagementApi: utils.Pointer(d.Get("cma").(bool)), } if fallbackCode, ok := d.GetOk("fallback_code"); ok { fallbackCodeStr := fallbackCode.(string) - locale.FallbackCode = &fallbackCodeStr + body.FallbackCode = &fallbackCodeStr } - err = localesClient.Upsert(context.Background(), locale) - + resp, err := client.CreateLocaleWithResponse(ctx, spaceID, environmentID, body) if err != nil { return parseError(err) } + if resp.StatusCode() != 201 { + return diag.Errorf("Failed to create locale") + } + + locale := resp.JSON201 diagErr := setLocaleProperties(d, locale) if diagErr != nil { return diagErr } - d.SetId(locale.Sys.ID) + d.SetId(*locale.Sys.Id) return nil } -func resourceReadLocale(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - client := m.(utils.ProviderData).CMAClient +func resourceReadLocale(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + client := m.(utils.ProviderData).Client spaceID := d.Get("space_id").(string) - localesClient := client.WithSpaceId(spaceID).WithEnvironment(d.Get("environment").(string)).Locales() + environmentId := d.Get("environment").(string) + localeId := d.Id() - locale, err := getLocale(d, localesClient) + locale, err := getLocale(ctx, client, spaceID, environmentId, localeId) + if err != nil { + return parseError(err) + } - var notFoundError *common.NotFoundError - if errors.As(err, ¬FoundError) { + if locale == nil { d.SetId("") return nil } - if err != nil { - return parseError(err) - } - diagErr := setLocaleProperties(d, locale) if diagErr != nil { return diagErr @@ -161,39 +160,39 @@ func resourceReadLocale(_ context.Context, d *schema.ResourceData, m interface{} return nil } -func resourceUpdateLocale(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - client := m.(utils.ProviderData).CMAClient +func resourceUpdateLocale(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + client := m.(utils.ProviderData).Client spaceID := d.Get("space_id").(string) - localesClient := client.WithSpaceId(spaceID).WithEnvironment(d.Get("environment").(string)).Locales() - - locale, err := getLocale(d, localesClient) + environmentId := d.Get("environment").(string) + localeId := d.Id() - if err != nil { - return parseError(err) + params := &sdk.UpdateLocaleParams{ + XContentfulVersion: d.Get("version").(int), + } + body := sdk.LocaleUpdate{ + Name: d.Get("name").(string), + Code: d.Get("code").(string), + FallbackCode: nil, + Optional: utils.Pointer(d.Get("optional").(bool)), + ContentDeliveryApi: utils.Pointer(d.Get("cda").(bool)), + ContentManagementApi: utils.Pointer(d.Get("cma").(bool)), } - - locale.Name = d.Get("name").(string) - locale.Code = d.Get("code").(string) - - locale.FallbackCode = nil if fallbackCode, ok := d.GetOk("fallback_code"); ok { - fallbackCodeStr := fallbackCode.(string) - - locale.FallbackCode = &fallbackCodeStr + body.FallbackCode = &fallbackCodeStr } - locale.Optional = d.Get("optional").(bool) - locale.CDA = d.Get("cda").(bool) - locale.CMA = d.Get("cma").(bool) - - err = localesClient.Upsert(context.Background(), locale) - + resp, err := client.UpdateLocaleWithResponse(ctx, spaceID, environmentId, localeId, params, body) if err != nil { return parseError(err) } + if resp.StatusCode() != 200 { + return diag.Errorf("Failed to update locale") + } + + locale := resp.JSON200 diagErr := setLocaleProperties(d, locale) if diagErr != nil { return diagErr @@ -203,31 +202,24 @@ func resourceUpdateLocale(_ context.Context, d *schema.ResourceData, m interface } func resourceDeleteLocale(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - client := m.(utils.ProviderData).CMAClient + client := m.(utils.ProviderData).Client spaceID := d.Get("space_id").(string) - localesClient := client.WithSpaceId(spaceID).WithEnvironment(d.Get("environment").(string)).Locales() - - locale, err := getLocale(d, localesClient) + environmentId := d.Get("environment").(string) + localeId := d.Id() + resp, err := client.DeleteLocaleWithResponse(ctx, spaceID, environmentId, localeId) if err != nil { return parseError(err) } - err = localesClient.Delete(context.Background(), locale) - - var notFoundError *common.NotFoundError - if errors.As(err, ¬FoundError) { - return nil - } - - if err != nil { - return parseError(err) + if resp.StatusCode() != 204 { + return diag.Errorf("Failed to delete locale") } return nil } -func setLocaleProperties(d *schema.ResourceData, locale *model.Locale) diag.Diagnostics { +func setLocaleProperties(d *schema.ResourceData, locale *sdk.Locale) diag.Diagnostics { err := d.Set("name", locale.Name) if err != nil { return diag.FromErr(err) @@ -248,12 +240,12 @@ func setLocaleProperties(d *schema.ResourceData, locale *model.Locale) diag.Diag return diag.FromErr(err) } - err = d.Set("cda", locale.CDA) + err = d.Set("cda", locale.ContentDeliveryApi) if err != nil { return diag.FromErr(err) } - err = d.Set("cma", locale.CMA) + err = d.Set("cma", locale.ContentManagementApi) if err != nil { return diag.FromErr(err) } @@ -266,6 +258,19 @@ func setLocaleProperties(d *schema.ResourceData, locale *model.Locale) diag.Diag return nil } -func getLocale(d *schema.ResourceData, client cma.Locales) (*model.Locale, error) { - return client.Get(context.Background(), d.Id()) +func getLocale(ctx context.Context, client *sdk.ClientWithResponses, spaceID, environmentId, localeId string) (*sdk.Locale, error) { + resp, err := client.GetLocaleWithResponse(ctx, spaceID, environmentId, localeId) + if err != nil { + return nil, err + } + + if resp.StatusCode() == 404 { + return nil, nil + } + + if resp.StatusCode() != 200 { + return nil, fmt.Errorf("Failed to read locale") + } + + return resp.JSON200, nil } diff --git a/contentful/resource_contentful_space.go b/contentful/resource_contentful_space.go index 7ba0d8c..6a74129 100644 --- a/contentful/resource_contentful_space.go +++ b/contentful/resource_contentful_space.go @@ -5,9 +5,9 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/labd/contentful-go" "github.com/labd/contentful-go/pkgs/common" + "github.com/labd/terraform-provider-contentful/internal/sdk" "github.com/labd/terraform-provider-contentful/internal/utils" ) @@ -19,6 +19,9 @@ func resourceContentfulSpace() *schema.Resource { ReadContext: resourceSpaceRead, UpdateContext: resourceSpaceUpdate, DeleteContext: resourceSpaceDelete, + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, Schema: map[string]*schema.Schema{ "version": { @@ -42,22 +45,28 @@ func resourceContentfulSpace() *schema.Resource { func resourceSpaceCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { client := m.(utils.ProviderData).Client - space := &contentful.Space{ + body := sdk.SpaceCreate{ Name: d.Get("name").(string), - DefaultLocale: d.Get("default_locale").(string), + DefaultLocale: utils.Pointer(d.Get("default_locale").(string)), } - err := client.Spaces.Upsert(space) + resp, err := client.CreateSpaceWithResponse(ctx, nil, body) if err != nil { return parseError(err) } + if resp.StatusCode() != 201 { + return diag.Errorf("Failed to create space") + } + + space := resp.JSON201 + err = updateSpaceProperties(d, space) if err != nil { return parseError(err) } - d.SetId(space.Sys.ID) + d.SetId(*space.Sys.Id) return nil } @@ -66,31 +75,64 @@ func resourceSpaceRead(ctx context.Context, d *schema.ResourceData, m interface{ client := m.(utils.ProviderData).Client spaceID := d.Id() - _, err := client.Spaces.Get(spaceID) - if _, ok := err.(common.NotFoundError); ok { + resp, err := client.GetSpaceWithResponse(ctx, spaceID) + if err != nil { + return parseError(err) + } + + if resp.StatusCode() == 404 { d.SetId("") return nil } - return parseError(err) + if resp.StatusCode() != 200 { + return diag.Errorf("Failed to retrieve space") + } + + err = updateSpaceProperties(d, resp.JSON200) + if err != nil { + return parseError(err) + } + + return nil } func resourceSpaceUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { client := m.(utils.ProviderData).Client spaceID := d.Id() - space, err := client.Spaces.Get(spaceID) + getResp, err := client.GetSpaceWithResponse(ctx, spaceID) if err != nil { return parseError(err) } - space.Name = d.Get("name").(string) + if getResp.StatusCode() != 200 { + return diag.Errorf("Failed to retrieve space") + } + + space := getResp.JSON200 + + // TODO: we can't update the default locale here, we need to do that via the + // locales endpoint, searching for the default locale + update := sdk.SpaceUpdate{ + Name: d.Get("name").(string), + } + + params := &sdk.UpdateSpaceParams{ + XContentfulVersion: d.Get("version").(int), + } - err = client.Spaces.Upsert(space) + resp, err := client.UpdateSpaceWithResponse(ctx, *space.Sys.Id, params, update) if err != nil { return parseError(err) } + if resp.StatusCode() != 200 { + return diag.Errorf("Failed to update space") + } + + space = resp.JSON200 + err = updateSpaceProperties(d, space) if err != nil { return parseError(err) @@ -103,20 +145,33 @@ func resourceSpaceDelete(ctx context.Context, d *schema.ResourceData, m interfac client := m.(utils.ProviderData).Client spaceID := d.Id() - space, err := client.Spaces.Get(spaceID) + getResp, err := client.GetSpaceWithResponse(ctx, spaceID) if err != nil { return parseError(err) } - err = client.Spaces.Delete(space) + if getResp.StatusCode() != 200 { + return diag.Errorf("Failed to retrieve space") + } + + params := &sdk.DeleteSpaceParams{ + XContentfulVersion: d.Get("version").(int), + } + + space := getResp.JSON200 + resp, err := client.DeleteSpaceWithResponse(ctx, *space.Sys.Id, params) if _, ok := err.(common.NotFoundError); ok { return nil } + if resp.StatusCode() != 204 { + return diag.Errorf("Failed to delete space") + } + return parseError(err) } -func updateSpaceProperties(d *schema.ResourceData, space *contentful.Space) error { +func updateSpaceProperties(d *schema.ResourceData, space *sdk.Space) error { err := d.Set("version", space.Sys.Version) if err != nil { return err diff --git a/contentful/resource_contentful_webhook.go b/contentful/resource_contentful_webhook.go index f0bad2a..f5accf7 100644 --- a/contentful/resource_contentful_webhook.go +++ b/contentful/resource_contentful_webhook.go @@ -5,9 +5,9 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/labd/contentful-go" "github.com/labd/contentful-go/pkgs/common" + "github.com/labd/terraform-provider-contentful/internal/sdk" "github.com/labd/terraform-provider-contentful/internal/utils" ) @@ -68,26 +68,31 @@ func resourceCreateWebhook(ctx context.Context, d *schema.ResourceData, m interf client := m.(utils.ProviderData).Client spaceID := d.Get("space_id").(string) - webhook := &contentful.Webhook{ + body := sdk.WebhookCreate{ Name: d.Get("name").(string), - URL: d.Get("url").(string), - Topics: transformTopicsToContentfulFormat(d.Get("topics").([]interface{})), + Url: d.Get("url").(string), + Topics: transformTopicsToContentfulFormat(d.Get("topics").([]any)), Headers: transformHeadersToContentfulFormat(d.Get("headers")), - HTTPBasicUsername: d.Get("http_basic_auth_username").(string), - HTTPBasicPassword: d.Get("http_basic_auth_password").(string), + HttpBasicUsername: utils.Pointer(d.Get("http_basic_auth_username").(string)), + HttpBasicPassword: utils.Pointer(d.Get("http_basic_auth_password").(string)), } - err := client.Webhooks.Upsert(spaceID, webhook) + resp, err := client.CreateWebhookWithResponse(ctx, spaceID, body) if err != nil { return parseError(err) } + if resp.StatusCode() != 201 { + return diag.Errorf("Failed to create webhook") + } + + webhook := resp.JSON201 err = setWebhookProperties(d, webhook) if err != nil { return parseError(err) } - d.SetId(webhook.Sys.ID) + d.SetId(*webhook.Sys.Id) return nil } @@ -97,29 +102,44 @@ func resourceUpdateWebhook(ctx context.Context, d *schema.ResourceData, m interf spaceID := d.Get("space_id").(string) webhookID := d.Id() - webhook, err := client.Webhooks.Get(spaceID, webhookID) + resp, err := client.GetWebhookWithResponse(ctx, spaceID, webhookID) if err != nil { return parseError(err) } - webhook.Name = d.Get("name").(string) - webhook.URL = d.Get("url").(string) - webhook.Topics = transformTopicsToContentfulFormat(d.Get("topics").([]interface{})) - webhook.Headers = transformHeadersToContentfulFormat(d.Get("headers")) - webhook.HTTPBasicUsername = d.Get("http_basic_auth_username").(string) - webhook.HTTPBasicPassword = d.Get("http_basic_auth_password").(string) + if resp.StatusCode() != 200 { + return diag.Errorf("Webhook not found") + } + + params := &sdk.UpdateWebhookParams{ + XContentfulVersion: d.Get("version").(int), + } + + update := sdk.WebhookUpdate{ + Name: d.Get("name").(string), + Url: d.Get("url").(string), + Topics: transformTopicsToContentfulFormat(d.Get("topics").([]any)), + Headers: transformHeadersToContentfulFormat(d.Get("headers")), + HttpBasicUsername: utils.Pointer(d.Get("http_basic_auth_username").(string)), + HttpBasicPassword: utils.Pointer(d.Get("http_basic_auth_password").(string)), + } - err = client.Webhooks.Upsert(spaceID, webhook) + updateResp, err := client.UpdateWebhookWithResponse(ctx, spaceID, webhookID, params, update) if err != nil { return parseError(err) } + if updateResp.StatusCode() != 200 { + return diag.Errorf("Failed to update webhook") + } + + webhook := updateResp.JSON200 err = setWebhookProperties(d, webhook) if err != nil { return parseError(err) } - d.SetId(webhook.Sys.ID) + d.SetId(*webhook.Sys.Id) return nil } @@ -129,7 +149,7 @@ func resourceReadWebhook(ctx context.Context, d *schema.ResourceData, m interfac spaceID := d.Get("space_id").(string) webhookID := d.Id() - webhook, err := client.Webhooks.Get(spaceID, webhookID) + resp, err := client.GetWebhookWithResponse(ctx, spaceID, webhookID) if _, ok := err.(common.NotFoundError); ok { d.SetId("") return nil @@ -139,6 +159,7 @@ func resourceReadWebhook(ctx context.Context, d *schema.ResourceData, m interfac return parseError(err) } + webhook := resp.JSON200 err = setWebhookProperties(d, webhook) if err != nil { return parseError(err) @@ -152,20 +173,23 @@ func resourceDeleteWebhook(ctx context.Context, d *schema.ResourceData, m interf spaceID := d.Get("space_id").(string) webhookID := d.Id() - webhook, err := client.Webhooks.Get(spaceID, webhookID) + params := &sdk.DeleteWebhookParams{ + XContentfulVersion: d.Get("version").(int), + } + + resp, err := client.DeleteWebhookWithResponse(ctx, spaceID, webhookID, params) if err != nil { return parseError(err) } - err = client.Webhooks.Delete(spaceID, webhook) - if _, ok := err.(common.NotFoundError); ok { - return nil + if resp.StatusCode() != 204 { + return diag.Errorf("Failed to delete webhook") } - return parseError(err) + return nil } -func setWebhookProperties(d *schema.ResourceData, webhook *contentful.Webhook) (err error) { +func setWebhookProperties(d *schema.ResourceData, webhook *sdk.Webhook) (err error) { headers := make(map[string]string) for _, entry := range webhook.Headers { headers[entry.Key] = entry.Value @@ -176,7 +200,7 @@ func setWebhookProperties(d *schema.ResourceData, webhook *contentful.Webhook) ( return err } - err = d.Set("space_id", webhook.Sys.Space.Sys.ID) + err = d.Set("space_id", webhook.Sys.Space.Sys.Id) if err != nil { return err } @@ -191,12 +215,12 @@ func setWebhookProperties(d *schema.ResourceData, webhook *contentful.Webhook) ( return err } - err = d.Set("url", webhook.URL) + err = d.Set("url", webhook.Url) if err != nil { return err } - err = d.Set("http_basic_auth_username", webhook.HTTPBasicUsername) + err = d.Set("http_basic_auth_username", webhook.HttpBasicUsername) if err != nil { return err } @@ -209,17 +233,20 @@ func setWebhookProperties(d *schema.ResourceData, webhook *contentful.Webhook) ( return nil } -func transformHeadersToContentfulFormat(headersTerraform interface{}) []*contentful.WebhookHeader { - var headers []*contentful.WebhookHeader +func transformHeadersToContentfulFormat(headersTerraform any) *[]sdk.WebhookHeader { + var headers []sdk.WebhookHeader for k, v := range headersTerraform.(map[string]interface{}) { - headers = append(headers, &contentful.WebhookHeader{ + headers = append(headers, sdk.WebhookHeader{ Key: k, Value: v.(string), }) } + if len(headers) == 0 { + return nil + } - return headers + return &headers } func transformTopicsToContentfulFormat(topicsTerraform []interface{}) []string { diff --git a/go.mod b/go.mod index 76929bc..1338e12 100644 --- a/go.mod +++ b/go.mod @@ -5,14 +5,19 @@ go 1.23.0 toolchain go1.23.7 require ( + github.com/deepmap/oapi-codegen v1.16.3 github.com/elliotchance/pie/v2 v2.9.1 github.com/hashicorp/terraform-plugin-docs v0.19.0 github.com/hashicorp/terraform-plugin-framework v1.14.1 github.com/hashicorp/terraform-plugin-framework-jsontypes v0.2.0 github.com/hashicorp/terraform-plugin-framework-validators v0.17.0 + github.com/hashicorp/terraform-plugin-log v0.9.0 github.com/hashicorp/terraform-plugin-mux v0.18.0 github.com/hashicorp/terraform-plugin-testing v1.12.0 github.com/labd/contentful-go v0.5.4-0.20250324140149-2fdab88b69c2 + github.com/oapi-codegen/nullable v1.1.0 + github.com/oapi-codegen/oapi-codegen/v2 v2.4.1 + github.com/oapi-codegen/runtime v1.1.1 github.com/stretchr/testify v1.9.0 ) @@ -23,29 +28,40 @@ require ( github.com/Masterminds/semver/v3 v3.2.1 // indirect github.com/Masterminds/sprig/v3 v3.2.3 // indirect github.com/ProtonMail/go-crypto v1.1.3 // indirect + github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect github.com/armon/go-radix v1.0.0 // indirect github.com/bgentry/speakeasy v0.1.0 // indirect github.com/bmatcuk/doublestar/v4 v4.6.1 // indirect github.com/cloudflare/circl v1.3.7 // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 // indirect + github.com/getkin/kin-openapi v0.127.0 // indirect + github.com/go-openapi/jsonpointer v0.21.0 // indirect + github.com/go-openapi/swag v0.23.0 // indirect github.com/google/uuid v1.6.0 // indirect github.com/hashicorp/cli v1.1.6 // indirect github.com/hashicorp/go-retryablehttp v0.7.7 // indirect github.com/hashicorp/hc-install v0.9.1 // indirect - github.com/hashicorp/terraform-plugin-log v0.9.0 // indirect github.com/hashicorp/terraform-registry-address v0.2.4 // indirect github.com/hashicorp/terraform-svchost v0.1.1 // indirect github.com/huandu/xstrings v1.4.0 // indirect github.com/imdario/mergo v0.3.16 // indirect + github.com/invopop/yaml v0.3.1 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-runewidth v0.0.15 // indirect + github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect + github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/posener/complete v1.2.3 // indirect github.com/rivo/uniseg v0.4.7 // indirect github.com/shopspring/decimal v1.4.0 // indirect + github.com/speakeasy-api/openapi-overlay v0.9.0 // indirect github.com/spf13/cast v1.6.0 // indirect github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect + github.com/vmware-labs/yaml-jsonpath v0.3.2 // indirect github.com/yuin/goldmark v1.7.1 // indirect github.com/yuin/goldmark-meta v1.1.0 // indirect go.abhg.dev/goldmark/frontmatter v0.2.0 // indirect diff --git a/go.sum b/go.sum index ade1caa..7c17a59 100644 --- a/go.sum +++ b/go.sum @@ -15,8 +15,11 @@ github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migc github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/ProtonMail/go-crypto v1.1.3 h1:nRBOetoydLeUb4nHajyO2bKqMLfWQ/ZPwkXqXxPxCFk= github.com/ProtonMail/go-crypto v1.1.3/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= +github.com/RaveNoX/go-jsoncommentstrip v1.0.0/go.mod h1:78ihd09MekBnJnxpICcwzCMzGrKSKYe4AqU6PDYYpjk= github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= +github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7Dml6nw9rQ= +github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP2+08jFMw88y4klk= github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec= github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY= github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4= @@ -24,10 +27,14 @@ 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/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w= github.com/bmatcuk/doublestar/v4 v4.6.1 h1:FH9SifrbvJhnlQpztAx++wlkk70QBf0iBWDwNy7PA4I= github.com/bmatcuk/doublestar/v4 v4.6.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA= github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +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/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= github.com/cyphar/filepath-securejoin v0.2.5 h1:6iR5tXJ/e6tJZzzdMc1km3Sa7RRIVBKAK32O2s7AYfo= @@ -35,6 +42,11 @@ github.com/cyphar/filepath-securejoin v0.2.5/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxG 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/deepmap/oapi-codegen v1.16.3 h1:GT9G86SbQtT1r8ZB+4Cybi9VGdu1P5ieNvNdEoCSbrA= +github.com/deepmap/oapi-codegen v1.16.3/go.mod h1:JD6ErqeX0nYnhdciLc61Konj3NBASREMlkHOgHn8WAM= +github.com/dprotaso/go-yit v0.0.0-20191028211022-135eb7262960/go.mod h1:9HQzr9D/0PGwMEbC3d5AB7oi67+h4TsQqItC1GVYG58= +github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 h1:PRxIJD8XjimM5aTknUK9w6DHLDox2r2M3DI4i2pnd3w= +github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936/go.mod h1:ttYvX5qlB+mlV1okblJqcSMtR4c52UKxDiX9GRBS8+Q= github.com/elliotchance/pie/v2 v2.9.1 h1:v7TdC6ZdNZJ1HACofpLXvGKHUk307AjY/bttwDPWKEQ= github.com/elliotchance/pie/v2 v2.9.1/go.mod h1:18t0dgGFH006g4eVdDtWfgFZPQEgl10IoEO8YWEq3Og= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= @@ -44,6 +56,11 @@ github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/getkin/kin-openapi v0.127.0 h1:Mghqi3Dhryf3F8vR370nN67pAERW+3a95vomb3MAREY= +github.com/getkin/kin-openapi v0.127.0/go.mod h1:OZrfXzUfGrNbsKj+xmFBx6E5c6yH3At/tAKSc2UszXM= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= github.com/go-git/go-billy/v5 v5.6.0 h1:w2hPNtoehvJIxR00Vb4xX94qHQi/ApZfX+nBE2Cjio8= @@ -54,19 +71,34 @@ github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -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-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= +github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= +github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= +github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= +github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -130,16 +162,23 @@ github.com/hashicorp/terraform-svchost v0.1.1 h1:EZZimZ1GxdqFRinZ1tpJwVxxt49xc/S github.com/hashicorp/terraform-svchost v0.1.1/go.mod h1:mNsjQfZyf/Jhz35v6/0LWcv26+X7JPS+buii2c9/ctc= github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE= github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU= github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= +github.com/invopop/yaml v0.3.1 h1:f0+ZpmhfBSS4MhG+4HYseMdJhoeeopbSKbq5Rpeelso= +github.com/invopop/yaml v0.3.1/go.mod h1:PMOp3nn4/12yEZUFfmOuNHJsZToEEOwoWsT+D81KkeA= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c= github.com/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE= github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= @@ -151,6 +190,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/labd/contentful-go v0.5.4-0.20250324140149-2fdab88b69c2 h1:Tz4faVF5rrjzHtOo7bR2fhEpooCXCbwFE42zyn6IFpQ= github.com/labd/contentful-go v0.5.4-0.20250324140149-2fdab88b69c2/go.mod h1:SrC2m8PCbpFiMkVJjODPI6e/8Nne6/Q27sxsXOiXs5A= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= @@ -174,8 +215,34 @@ github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/oapi-codegen/nullable v1.1.0 h1:eAh8JVc5430VtYVnq00Hrbpag9PFRGWLjxR1/3KntMs= +github.com/oapi-codegen/nullable v1.1.0/go.mod h1:KUZ3vUzkmEKY90ksAmit2+5juDIhIZhfDl+0PwOQlFY= +github.com/oapi-codegen/oapi-codegen/v2 v2.4.1 h1:ykgG34472DWey7TSjd8vIfNykXgjOgYJZoQbKfEeY/Q= +github.com/oapi-codegen/oapi-codegen/v2 v2.4.1/go.mod h1:N5+lY1tiTDV3V1BeHtOxeWXHoPVeApvsvjJqegfoaz8= +github.com/oapi-codegen/runtime v1.1.1 h1:EXLHh0DXIJnWhdRPN2w4MXAzFyE4CskzhNLUmtpMYro= +github.com/oapi-codegen/runtime v1.1.1/go.mod h1:SK9X900oXmPWilYR5/WKPzt3Kqxn/uS/+lbpREv+eCg= github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA= github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= +github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg= +github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= +github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -187,6 +254,7 @@ github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= @@ -194,16 +262,22 @@ github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME= github.com/skeema/knownhosts v1.3.0 h1:AM+y0rI04VksttfwjkSTNQorvGqmwATnvnAHpSgc0LY= github.com/skeema/knownhosts v1.3.0/go.mod h1:sPINvnADmT/qYH1kfv+ePMmOBTH6Tbl7b5LvTDjFK7M= +github.com/speakeasy-api/openapi-overlay v0.9.0 h1:Wrz6NO02cNlLzx1fB093lBlYxSI54VRhy1aSutx0PQg= +github.com/speakeasy-api/openapi-overlay v0.9.0/go.mod h1:f5FloQrHA7MsxYg9djzMD5h6dxrHjVVByWKh7an8TRc= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= +github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= +github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI= github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= @@ -211,8 +285,11 @@ github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IU github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok= github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= +github.com/vmware-labs/yaml-jsonpath v0.3.2 h1:/5QKeCBGdsInyDCyVNLbXyilb61MXGi9NP674f9Hobk= +github.com/vmware-labs/yaml-jsonpath v0.3.2/go.mod h1:U6whw1z03QyqgWdgXxvVnQ90zN1BWz5V+51Ewf8k+rQ= github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/goldmark v1.7.1 h1:3bajkSilaCbjdKVsKdZjZCLBNPL9pYzrCakKaf4U49U= github.com/yuin/goldmark v1.7.1/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= @@ -235,34 +312,54 @@ go.opentelemetry.io/otel/sdk/metric v1.31.0/go.mod h1:CRInTMVvNhUKgSAMbKyTMxqOBC go.opentelemetry.io/otel/trace v1.31.0 h1:ffjsj1aRouKewfr85U2aGagJ46+MvodynlQ1HYdmJys= go.opentelemetry.io/otel/trace v1.31.0/go.mod h1:TXZkRk7SM2ZQLtR6eoAWQFIHPvzQ06FJAsO1tJg480A= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f h1:99ci1mjWVBWwJiEKYY6jWa4d2nTQVIEhZIptnrVb1XY= golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4= golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c= golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/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-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -278,6 +375,7 @@ golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y= golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= @@ -285,11 +383,14 @@ golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= @@ -297,19 +398,34 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53 h1: google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI= google.golang.org/grpc v1.69.4 h1:MF5TftSMkd8GLw/m0KM6V8CMOCY6NZ1NQDPGFgbTt4A= google.golang.org/grpc v1.69.4/go.mod h1:vyjdE6jLBI76dgpDojsFGNaHlxdjXN9ghpnd2o7JGZ4= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.36.3 h1:82DV7MYdb8anAVi3qge1wSnMDrnKK7ebr+I0hHRN1BU= google.golang.org/protobuf v1.36.3/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20191026110619-0b21df46bc1d/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= moul.io/http2curl v1.0.1-0.20190925090545-5cd742060b0e h1:C7q+e9M5nggAvWfVg9Nl66kebKeuJlP3FD58V4RR5wo= diff --git a/internal/provider/provider.go b/internal/provider/provider.go index abe2708..d492a1d 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -138,7 +138,6 @@ func (c contentfulProvider) Configure(ctx context.Context, request provider.Conf } data := utils.ProviderData{ - Client: cma, CMAClient: client, OrganizationId: organizationId, } diff --git a/internal/resources/app_definition/resource.go b/internal/resources/app_definition/resource.go index f253ae5..cd001db 100644 --- a/internal/resources/app_definition/resource.go +++ b/internal/resources/app_definition/resource.go @@ -18,6 +18,7 @@ import ( "github.com/labd/contentful-go" "github.com/labd/contentful-go/pkgs/model" "github.com/labd/contentful-go/service/cma" + "github.com/labd/terraform-provider-contentful/internal/custommodifier" "github.com/labd/terraform-provider-contentful/internal/customvalidator" "github.com/labd/terraform-provider-contentful/internal/utils" @@ -163,7 +164,7 @@ func (e *appDefinitionResource) Configure(_ context.Context, request resource.Co data := request.ProviderData.(utils.ProviderData) e.client = data.CMAClient.WithOrganizationId(data.OrganizationId) e.organizationId = data.OrganizationId - e.clientAppUpload = data.Client + e.clientAppUpload = data.ClientOld } diff --git a/internal/resources/contenttype/resource.go b/internal/resources/contenttype/resource.go index 363df68..7f0e7d0 100644 --- a/internal/resources/contenttype/resource.go +++ b/internal/resources/contenttype/resource.go @@ -24,6 +24,7 @@ import ( "github.com/labd/contentful-go" "github.com/labd/contentful-go/pkgs/model" "github.com/labd/contentful-go/service/cma" + "github.com/labd/terraform-provider-contentful/internal/custommodifier" "github.com/labd/terraform-provider-contentful/internal/customvalidator" "github.com/labd/terraform-provider-contentful/internal/utils" @@ -381,7 +382,7 @@ func (e *contentTypeResource) Configure(_ context.Context, request resource.Conf data := request.ProviderData.(utils.ProviderData) e.client = data.CMAClient - e.clientOld = data.Client + e.clientOld = data.ClientOld } diff --git a/internal/sdk/main.gen.go b/internal/sdk/main.gen.go new file mode 100644 index 0000000..1180f44 --- /dev/null +++ b/internal/sdk/main.gen.go @@ -0,0 +1,5575 @@ +// Package sdk provides primitives to interact with the openapi HTTP API. +// +// Code generated by github.com/oapi-codegen/oapi-codegen/v2 version v2.4.1 DO NOT EDIT. +package sdk + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "net/url" + "strings" + "time" + + "github.com/oapi-codegen/runtime" +) + +const ( + BearerAuthScopes = "bearerAuth.Scopes" +) + +// Defines values for AssetCollectionSysType. +const ( + AssetCollectionSysTypeArray AssetCollectionSysType = "Array" +) + +// Defines values for ContentTypeCollectionSysType. +const ( + ContentTypeCollectionSysTypeArray ContentTypeCollectionSysType = "Array" +) + +// Defines values for EntryCollectionSysType. +const ( + EntryCollectionSysTypeArray EntryCollectionSysType = "Array" +) + +// Defines values for EnvironmentCollectionSysType. +const ( + EnvironmentCollectionSysTypeArray EnvironmentCollectionSysType = "Array" +) + +// Defines values for EnvironmentSystemPropertiesSysLinkType. +const ( + EnvironmentSystemPropertiesSysLinkTypeEnvironment EnvironmentSystemPropertiesSysLinkType = "Environment" +) + +// Defines values for EnvironmentSystemPropertiesSysType. +const ( + EnvironmentSystemPropertiesSysTypeLink EnvironmentSystemPropertiesSysType = "Link" +) + +// Defines values for FieldLinkType. +const ( + FieldLinkTypeAsset FieldLinkType = "Asset" + FieldLinkTypeEntry FieldLinkType = "Entry" +) + +// Defines values for FieldType. +const ( + FieldTypeArray FieldType = "Array" + FieldTypeBoolean FieldType = "Boolean" + FieldTypeDate FieldType = "Date" + FieldTypeInteger FieldType = "Integer" + FieldTypeLink FieldType = "Link" + FieldTypeLocation FieldType = "Location" + FieldTypeNumber FieldType = "Number" + FieldTypeObject FieldType = "Object" + FieldTypeSymbol FieldType = "Symbol" + FieldTypeText FieldType = "Text" +) + +// Defines values for LocaleCollectionSysType. +const ( + LocaleCollectionSysTypeArray LocaleCollectionSysType = "Array" +) + +// Defines values for SpaceCollectionSysType. +const ( + SpaceCollectionSysTypeArray SpaceCollectionSysType = "Array" +) + +// Defines values for SystemPropertiesContentTypeSysLinkType. +const ( + SystemPropertiesContentTypeSysLinkTypeContentType SystemPropertiesContentTypeSysLinkType = "ContentType" +) + +// Defines values for SystemPropertiesContentTypeSysType. +const ( + SystemPropertiesContentTypeSysTypeLink SystemPropertiesContentTypeSysType = "Link" +) + +// Defines values for SystemPropertiesEnvironmentSysLinkType. +const ( + SystemPropertiesEnvironmentSysLinkTypeEnvironment SystemPropertiesEnvironmentSysLinkType = "Environment" +) + +// Defines values for SystemPropertiesEnvironmentSysType. +const ( + SystemPropertiesEnvironmentSysTypeLink SystemPropertiesEnvironmentSysType = "Link" +) + +// Defines values for WebhookCollectionSysType. +const ( + Array WebhookCollectionSysType = "Array" +) + +// Asset defines model for Asset. +type Asset struct { + Fields *struct { + // Description Asset description by locale + Description *map[string]string `json:"description,omitempty"` + + // File Asset file details by locale + File *map[string]struct { + ContentType *string `json:"contentType,omitempty"` + Details *struct { + Image *struct { + Height *int `json:"height,omitempty"` + Width *int `json:"width,omitempty"` + } `json:"image,omitempty"` + Size *int `json:"size,omitempty"` + } `json:"details,omitempty"` + FileName *string `json:"fileName,omitempty"` + Url *string `json:"url,omitempty"` + } `json:"file,omitempty"` + + // Title Asset title by locale + Title *map[string]string `json:"title,omitempty"` + } `json:"fields,omitempty"` + Sys *SystemProperties `json:"sys,omitempty"` +} + +// AssetCollection defines model for AssetCollection. +type AssetCollection struct { + Items *[]Asset `json:"items,omitempty"` + + // Limit Maximum number of assets returned + Limit *int `json:"limit,omitempty"` + + // Skip Number of assets skipped + Skip *int `json:"skip,omitempty"` + Sys *struct { + Type *AssetCollectionSysType `json:"type,omitempty"` + } `json:"sys,omitempty"` + + // Total Total number of assets + Total *int `json:"total,omitempty"` +} + +// AssetCollectionSysType defines model for AssetCollection.Sys.Type. +type AssetCollectionSysType string + +// AssetCreate defines model for AssetCreate. +type AssetCreate struct { + Fields *struct { + // Description Asset description by locale + Description *map[string]string `json:"description,omitempty"` + + // File Asset file details by locale + File *map[string]struct { + ContentType *string `json:"contentType,omitempty"` + FileName *string `json:"fileName,omitempty"` + + // Upload Upload URL + Upload *string `json:"upload,omitempty"` + } `json:"file,omitempty"` + + // Title Asset title by locale + Title *map[string]string `json:"title,omitempty"` + } `json:"fields,omitempty"` +} + +// ContentType defines model for ContentType. +type ContentType struct { + // Description Description of the content type + Description *string `json:"description,omitempty"` + + // DisplayField ID of the field to use as the display field + DisplayField *string `json:"displayField,omitempty"` + Fields *[]Field `json:"fields,omitempty"` + + // Name Name of the content type + Name *string `json:"name,omitempty"` + Sys *SystemProperties `json:"sys,omitempty"` +} + +// ContentTypeCollection defines model for ContentTypeCollection. +type ContentTypeCollection struct { + Items *[]ContentType `json:"items,omitempty"` + + // Limit Maximum number of content types returned + Limit *int `json:"limit,omitempty"` + + // Skip Number of content types skipped + Skip *int `json:"skip,omitempty"` + Sys *struct { + Type *ContentTypeCollectionSysType `json:"type,omitempty"` + } `json:"sys,omitempty"` + + // Total Total number of content types + Total *int `json:"total,omitempty"` +} + +// ContentTypeCollectionSysType defines model for ContentTypeCollection.Sys.Type. +type ContentTypeCollectionSysType string + +// ContentTypeCreate defines model for ContentTypeCreate. +type ContentTypeCreate struct { + // Description Description of the content type + Description *string `json:"description,omitempty"` + + // DisplayField ID of the field to use as the display field + DisplayField *string `json:"displayField,omitempty"` + Fields []Field `json:"fields"` + + // Name Name of the content type + Name string `json:"name"` +} + +// Entry defines model for Entry. +type Entry struct { + // Fields Content fields with values by locale + Fields *map[string]interface{} `json:"fields,omitempty"` + Sys *SystemProperties `json:"sys,omitempty"` +} + +// EntryCollection defines model for EntryCollection. +type EntryCollection struct { + Items *[]Entry `json:"items,omitempty"` + + // Limit Maximum number of entries returned + Limit *int `json:"limit,omitempty"` + + // Skip Number of entries skipped + Skip *int `json:"skip,omitempty"` + Sys *struct { + Type *EntryCollectionSysType `json:"type,omitempty"` + } `json:"sys,omitempty"` + + // Total Total number of entries + Total *int `json:"total,omitempty"` +} + +// EntryCollectionSysType defines model for EntryCollection.Sys.Type. +type EntryCollectionSysType string + +// EntryCreate defines model for EntryCreate. +type EntryCreate struct { + // Fields Content fields with values by locale + Fields *map[string]interface{} `json:"fields,omitempty"` +} + +// EntryUpdate defines model for EntryUpdate. +type EntryUpdate struct { + // Fields Content fields with values by locale + Fields *map[string]interface{} `json:"fields,omitempty"` +} + +// Environment defines model for Environment. +type Environment struct { + // Name Name of the environment + Name *string `json:"name,omitempty"` + Sys *SystemProperties `json:"sys,omitempty"` +} + +// EnvironmentCollection defines model for EnvironmentCollection. +type EnvironmentCollection struct { + Items *[]Environment `json:"items,omitempty"` + + // Limit Maximum number of environments returned + Limit *int `json:"limit,omitempty"` + + // Skip Number of environments skipped + Skip *int `json:"skip,omitempty"` + Sys *struct { + Type *EnvironmentCollectionSysType `json:"type,omitempty"` + } `json:"sys,omitempty"` + + // Total Total number of environments + Total *int `json:"total,omitempty"` +} + +// EnvironmentCollectionSysType defines model for EnvironmentCollection.Sys.Type. +type EnvironmentCollectionSysType string + +// EnvironmentCreate defines model for EnvironmentCreate. +type EnvironmentCreate struct { + // Name Name of the environment to create + Name string `json:"name"` +} + +// EnvironmentSystemProperties defines model for EnvironmentSystemProperties. +type EnvironmentSystemProperties struct { + Sys *struct { + // Id Environment ID + Id *string `json:"id,omitempty"` + LinkType *EnvironmentSystemPropertiesSysLinkType `json:"linkType,omitempty"` + Type *EnvironmentSystemPropertiesSysType `json:"type,omitempty"` + } `json:"sys,omitempty"` +} + +// EnvironmentSystemPropertiesSysLinkType defines model for EnvironmentSystemProperties.Sys.LinkType. +type EnvironmentSystemPropertiesSysLinkType string + +// EnvironmentSystemPropertiesSysType defines model for EnvironmentSystemProperties.Sys.Type. +type EnvironmentSystemPropertiesSysType string + +// EnvironmentUpdate defines model for EnvironmentUpdate. +type EnvironmentUpdate struct { + // Name Updated name for the environment + Name string `json:"name"` +} + +// Field defines model for Field. +type Field struct { + // Id ID of the field + Id string `json:"id"` + + // Items Used for Array fields to define the items type + Items *map[string]interface{} `json:"items,omitempty"` + + // LinkType For Link fields, defines what type of resource it links to + LinkType *FieldLinkType `json:"linkType,omitempty"` + + // Localized Whether the field is localized + Localized *bool `json:"localized,omitempty"` + + // Name Name of the field + Name string `json:"name"` + + // Required Whether the field is required + Required *bool `json:"required,omitempty"` + + // Type Type of the field + Type FieldType `json:"type"` +} + +// FieldLinkType For Link fields, defines what type of resource it links to +type FieldLinkType string + +// FieldType Type of the field +type FieldType string + +// Locale defines model for Locale. +type Locale struct { + // Code Locale code (e.g., en-US, de-DE) + Code *string `json:"code,omitempty"` + + // ContentDeliveryApi Whether this locale is available in the content delivery API + ContentDeliveryApi *bool `json:"contentDeliveryApi,omitempty"` + + // ContentManagementApi Whether this locale is available in the content management API + ContentManagementApi *bool `json:"contentManagementApi,omitempty"` + + // Default Whether this is the default locale + Default *bool `json:"default,omitempty"` + + // FallbackCode Code of the locale to use as a fallback + FallbackCode *string `json:"fallbackCode,omitempty"` + + // Name Human readable name of the locale + Name *string `json:"name,omitempty"` + + // Optional Whether this locale is optional for content + Optional *bool `json:"optional,omitempty"` + Sys *SystemProperties `json:"sys,omitempty"` +} + +// LocaleCollection defines model for LocaleCollection. +type LocaleCollection struct { + Items *[]Locale `json:"items,omitempty"` + + // Limit Maximum number of locales returned + Limit *int `json:"limit,omitempty"` + + // Skip Number of locales skipped + Skip *int `json:"skip,omitempty"` + Sys *struct { + Type *LocaleCollectionSysType `json:"type,omitempty"` + } `json:"sys,omitempty"` + + // Total Total number of locales + Total *int `json:"total,omitempty"` +} + +// LocaleCollectionSysType defines model for LocaleCollection.Sys.Type. +type LocaleCollectionSysType string + +// LocaleCreate defines model for LocaleCreate. +type LocaleCreate struct { + // Code Locale code (e.g., en-US, de-DE) + Code string `json:"code"` + + // ContentDeliveryApi Whether this locale is available in the content delivery API + ContentDeliveryApi *bool `json:"contentDeliveryApi,omitempty"` + + // ContentManagementApi Whether this locale is available in the content management API + ContentManagementApi *bool `json:"contentManagementApi,omitempty"` + + // Default Whether this is the default locale + Default *bool `json:"default,omitempty"` + + // FallbackCode Code of the locale to use as a fallback + FallbackCode *string `json:"fallbackCode"` + + // Name Human readable name of the locale + Name string `json:"name"` + + // Optional Whether this locale is optional for content + Optional *bool `json:"optional,omitempty"` +} + +// LocaleUpdate defines model for LocaleUpdate. +type LocaleUpdate struct { + // Code Locale code (e.g., en-US, de-DE) + Code string `json:"code"` + + // ContentDeliveryApi Whether this locale is available in the content delivery API + ContentDeliveryApi *bool `json:"contentDeliveryApi,omitempty"` + + // ContentManagementApi Whether this locale is available in the content management API + ContentManagementApi *bool `json:"contentManagementApi,omitempty"` + + // FallbackCode Code of the locale to use as a fallback + FallbackCode *string `json:"fallbackCode"` + + // Name Human readable name of the locale + Name string `json:"name"` + + // Optional Whether this locale is optional for content + Optional *bool `json:"optional,omitempty"` +} + +// Space defines model for Space. +type Space struct { + // DefaultLocale Default locale of the space + DefaultLocale *string `json:"defaultLocale,omitempty"` + + // Name Name of the space + Name *string `json:"name,omitempty"` + Sys *SystemProperties `json:"sys,omitempty"` +} + +// SpaceCollection defines model for SpaceCollection. +type SpaceCollection struct { + Items *[]Space `json:"items,omitempty"` + + // Limit Maximum number of spaces returned + Limit *int `json:"limit,omitempty"` + + // Skip Number of spaces skipped + Skip *int `json:"skip,omitempty"` + Sys *struct { + Type *SpaceCollectionSysType `json:"type,omitempty"` + } `json:"sys,omitempty"` + + // Total Total number of spaces + Total *int `json:"total,omitempty"` +} + +// SpaceCollectionSysType defines model for SpaceCollection.Sys.Type. +type SpaceCollectionSysType string + +// SpaceCreate defines model for SpaceCreate. +type SpaceCreate struct { + // DefaultLocale Default locale for the space + DefaultLocale *string `json:"defaultLocale,omitempty"` + + // Name Name of the space to create + Name string `json:"name"` +} + +// SpaceUpdate defines model for SpaceUpdate. +type SpaceUpdate struct { + // Name Updated name for the space + Name string `json:"name"` +} + +// SystemProperties defines model for SystemProperties. +type SystemProperties struct { + // ArchivedAt Archival timestamp + ArchivedAt *time.Time `json:"archivedAt,omitempty"` + ContentType *struct { + Sys *struct { + // Id Content type ID + Id *string `json:"id,omitempty"` + LinkType *SystemPropertiesContentTypeSysLinkType `json:"linkType,omitempty"` + Type *SystemPropertiesContentTypeSysType `json:"type,omitempty"` + } `json:"sys,omitempty"` + } `json:"contentType,omitempty"` + + // CreatedAt Creation timestamp + CreatedAt *time.Time `json:"createdAt,omitempty"` + Environment *struct { + Sys *struct { + // Id Environment ID + Id *string `json:"id,omitempty"` + LinkType *SystemPropertiesEnvironmentSysLinkType `json:"linkType,omitempty"` + Type *SystemPropertiesEnvironmentSysType `json:"type,omitempty"` + } `json:"sys,omitempty"` + } `json:"environment,omitempty"` + + // Id Resource ID + Id *string `json:"id,omitempty"` + + // PublishedAt Publication timestamp + PublishedAt *time.Time `json:"publishedAt,omitempty"` + Space *EnvironmentSystemProperties `json:"space,omitempty"` + + // Type Resource type + Type *string `json:"type,omitempty"` + + // UpdatedAt Last update timestamp + UpdatedAt *time.Time `json:"updatedAt,omitempty"` + + // Version Resource version + Version *int `json:"version,omitempty"` +} + +// SystemPropertiesContentTypeSysLinkType defines model for SystemProperties.ContentType.Sys.LinkType. +type SystemPropertiesContentTypeSysLinkType string + +// SystemPropertiesContentTypeSysType defines model for SystemProperties.ContentType.Sys.Type. +type SystemPropertiesContentTypeSysType string + +// SystemPropertiesEnvironmentSysLinkType defines model for SystemProperties.Environment.Sys.LinkType. +type SystemPropertiesEnvironmentSysLinkType string + +// SystemPropertiesEnvironmentSysType defines model for SystemProperties.Environment.Sys.Type. +type SystemPropertiesEnvironmentSysType string + +// Webhook defines model for Webhook. +type Webhook struct { + // Headers HTTP headers to send with the webhook request + Headers []WebhookHeader `json:"headers"` + + // HttpBasicPassword Password for HTTP basic authentication + HttpBasicPassword *string `json:"httpBasicPassword,omitempty"` + + // HttpBasicUsername Username for HTTP basic authentication + HttpBasicUsername *string `json:"httpBasicUsername,omitempty"` + + // Name Name of the webhook + Name string `json:"name"` + Sys *SystemProperties `json:"sys,omitempty"` + + // Topics Events that trigger the webhook + Topics []string `json:"topics"` + + // Url URL to call when the webhook is triggered + Url string `json:"url"` +} + +// WebhookCollection defines model for WebhookCollection. +type WebhookCollection struct { + Items *[]Webhook `json:"items,omitempty"` + + // Limit Maximum number of webhooks returned + Limit *int `json:"limit,omitempty"` + + // Skip Number of webhooks skipped + Skip *int `json:"skip,omitempty"` + Sys *struct { + Type *WebhookCollectionSysType `json:"type,omitempty"` + } `json:"sys,omitempty"` + + // Total Total number of webhooks + Total *int `json:"total,omitempty"` +} + +// WebhookCollectionSysType defines model for WebhookCollection.Sys.Type. +type WebhookCollectionSysType string + +// WebhookCreate defines model for WebhookCreate. +type WebhookCreate struct { + // Headers HTTP headers to send with the webhook request + Headers *[]WebhookHeader `json:"headers,omitempty"` + + // HttpBasicPassword Password for HTTP basic authentication + HttpBasicPassword *string `json:"httpBasicPassword,omitempty"` + + // HttpBasicUsername Username for HTTP basic authentication + HttpBasicUsername *string `json:"httpBasicUsername,omitempty"` + + // Name Name of the webhook + Name string `json:"name"` + + // Topics Events that trigger the webhook + Topics []string `json:"topics"` + + // Url URL to call when the webhook is triggered + Url string `json:"url"` +} + +// WebhookHeader defines model for WebhookHeader. +type WebhookHeader struct { + Key string `json:"key"` + Value string `json:"value"` +} + +// WebhookUpdate defines model for WebhookUpdate. +type WebhookUpdate struct { + // Headers HTTP headers to send with the webhook request + Headers *[]WebhookHeader `json:"headers,omitempty"` + + // HttpBasicPassword Password for HTTP basic authentication + HttpBasicPassword *string `json:"httpBasicPassword,omitempty"` + + // HttpBasicUsername Username for HTTP basic authentication + HttpBasicUsername *string `json:"httpBasicUsername,omitempty"` + + // Name Name of the webhook + Name string `json:"name"` + + // Topics Events that trigger the webhook + Topics []string `json:"topics"` + + // Url URL to call when the webhook is triggered + Url string `json:"url"` +} + +// ContentTypeHeader defines model for contentTypeHeader. +type ContentTypeHeader = string + +// EntryId defines model for entryId. +type EntryId = string + +// EnvironmentId defines model for environmentId. +type EnvironmentId = string + +// Limit defines model for limit. +type Limit = int + +// LocaleId defines model for localeId. +type LocaleId = string + +// ResourceVersion defines model for resourceVersion. +type ResourceVersion = int + +// Skip defines model for skip. +type Skip = int + +// SpaceId defines model for spaceId. +type SpaceId = string + +// WebhookId defines model for webhookId. +type WebhookId = string + +// GetAllSpacesParams defines parameters for GetAllSpaces. +type GetAllSpacesParams struct { + // Limit Maximum number of items to return + Limit *Limit `form:"limit,omitempty" json:"limit,omitempty"` + + // Skip Number of items to skip + Skip *Skip `form:"skip,omitempty" json:"skip,omitempty"` +} + +// CreateSpaceParams defines parameters for CreateSpace. +type CreateSpaceParams struct { + // ContentType Contentful Management API version header + ContentType ContentTypeHeader `json:"Content-Type"` +} + +// DeleteSpaceParams defines parameters for DeleteSpace. +type DeleteSpaceParams struct { + // XContentfulVersion The version of the locale to update. + XContentfulVersion ResourceVersion `json:"X-Contentful-Version"` +} + +// UpdateSpaceParams defines parameters for UpdateSpace. +type UpdateSpaceParams struct { + // XContentfulVersion The version of the locale to update. + XContentfulVersion ResourceVersion `json:"X-Contentful-Version"` +} + +// GetAllEnvironmentsParams defines parameters for GetAllEnvironments. +type GetAllEnvironmentsParams struct { + // Limit Maximum number of items to return + Limit *Limit `form:"limit,omitempty" json:"limit,omitempty"` + + // Skip Number of items to skip + Skip *Skip `form:"skip,omitempty" json:"skip,omitempty"` +} + +// DeleteEnvironmentParams defines parameters for DeleteEnvironment. +type DeleteEnvironmentParams struct { + // XContentfulVersion The version of the locale to update. + XContentfulVersion ResourceVersion `json:"X-Contentful-Version"` +} + +// UpdateEnvironmentParams defines parameters for UpdateEnvironment. +type UpdateEnvironmentParams struct { + // XContentfulVersion The version of the locale to update. + XContentfulVersion ResourceVersion `json:"X-Contentful-Version"` +} + +// GetAllAssetsParams defines parameters for GetAllAssets. +type GetAllAssetsParams struct { + // Limit Maximum number of items to return + Limit *Limit `form:"limit,omitempty" json:"limit,omitempty"` + + // Skip Number of items to skip + Skip *Skip `form:"skip,omitempty" json:"skip,omitempty"` +} + +// GetAllContentTypesParams defines parameters for GetAllContentTypes. +type GetAllContentTypesParams struct { + // Limit Maximum number of items to return + Limit *Limit `form:"limit,omitempty" json:"limit,omitempty"` + + // Skip Number of items to skip + Skip *Skip `form:"skip,omitempty" json:"skip,omitempty"` +} + +// GetAllEntriesParams defines parameters for GetAllEntries. +type GetAllEntriesParams struct { + // Limit Maximum number of items to return + Limit *Limit `form:"limit,omitempty" json:"limit,omitempty"` + + // Skip Number of items to skip + Skip *Skip `form:"skip,omitempty" json:"skip,omitempty"` + + // ContentType Filter by content type + ContentType *string `form:"content_type,omitempty" json:"content_type,omitempty"` +} + +// CreateEntryParams defines parameters for CreateEntry. +type CreateEntryParams struct { + // ContentType Content type ID for the new entry + ContentType string `form:"content_type" json:"content_type"` +} + +// DeleteEntryParams defines parameters for DeleteEntry. +type DeleteEntryParams struct { + // XContentfulVersion The version of the locale to update. + XContentfulVersion ResourceVersion `json:"X-Contentful-Version"` +} + +// UpdateEntryParams defines parameters for UpdateEntry. +type UpdateEntryParams struct { + // XContentfulVersion The version of the locale to update. + XContentfulVersion ResourceVersion `json:"X-Contentful-Version"` +} + +// GetAllLocalesParams defines parameters for GetAllLocales. +type GetAllLocalesParams struct { + // Limit Maximum number of items to return + Limit *Limit `form:"limit,omitempty" json:"limit,omitempty"` + + // Skip Number of items to skip + Skip *Skip `form:"skip,omitempty" json:"skip,omitempty"` +} + +// UpdateLocaleParams defines parameters for UpdateLocale. +type UpdateLocaleParams struct { + // XContentfulVersion The version of the locale to update. + XContentfulVersion ResourceVersion `json:"X-Contentful-Version"` +} + +// GetAllWebhooksParams defines parameters for GetAllWebhooks. +type GetAllWebhooksParams struct { + // Limit Maximum number of items to return + Limit *Limit `form:"limit,omitempty" json:"limit,omitempty"` + + // Skip Number of items to skip + Skip *Skip `form:"skip,omitempty" json:"skip,omitempty"` +} + +// DeleteWebhookParams defines parameters for DeleteWebhook. +type DeleteWebhookParams struct { + // XContentfulVersion The version of the locale to update. + XContentfulVersion ResourceVersion `json:"X-Contentful-Version"` +} + +// UpdateWebhookParams defines parameters for UpdateWebhook. +type UpdateWebhookParams struct { + // XContentfulVersion The version of the locale to update. + XContentfulVersion ResourceVersion `json:"X-Contentful-Version"` +} + +// CreateSpaceJSONRequestBody defines body for CreateSpace for application/json ContentType. +type CreateSpaceJSONRequestBody = SpaceCreate + +// UpdateSpaceJSONRequestBody defines body for UpdateSpace for application/json ContentType. +type UpdateSpaceJSONRequestBody = SpaceUpdate + +// CreateEnvironmentJSONRequestBody defines body for CreateEnvironment for application/json ContentType. +type CreateEnvironmentJSONRequestBody = EnvironmentCreate + +// UpdateEnvironmentJSONRequestBody defines body for UpdateEnvironment for application/json ContentType. +type UpdateEnvironmentJSONRequestBody = EnvironmentUpdate + +// CreateAssetJSONRequestBody defines body for CreateAsset for application/json ContentType. +type CreateAssetJSONRequestBody = AssetCreate + +// CreateContentTypeJSONRequestBody defines body for CreateContentType for application/json ContentType. +type CreateContentTypeJSONRequestBody = ContentTypeCreate + +// CreateEntryJSONRequestBody defines body for CreateEntry for application/json ContentType. +type CreateEntryJSONRequestBody = EntryCreate + +// UpdateEntryJSONRequestBody defines body for UpdateEntry for application/json ContentType. +type UpdateEntryJSONRequestBody = EntryUpdate + +// CreateLocaleJSONRequestBody defines body for CreateLocale for application/json ContentType. +type CreateLocaleJSONRequestBody = LocaleCreate + +// UpdateLocaleJSONRequestBody defines body for UpdateLocale for application/json ContentType. +type UpdateLocaleJSONRequestBody = LocaleUpdate + +// CreateWebhookJSONRequestBody defines body for CreateWebhook for application/json ContentType. +type CreateWebhookJSONRequestBody = WebhookCreate + +// UpdateWebhookJSONRequestBody defines body for UpdateWebhook for application/json ContentType. +type UpdateWebhookJSONRequestBody = WebhookUpdate + +// RequestEditorFn is the function signature for the RequestEditor callback function +type RequestEditorFn func(ctx context.Context, req *http.Request) error + +// Doer performs HTTP requests. +// +// The standard http.Client implements this interface. +type HttpRequestDoer interface { + Do(req *http.Request) (*http.Response, error) +} + +// Client which conforms to the OpenAPI3 specification for this service. +type Client struct { + // The endpoint of the server conforming to this interface, with scheme, + // https://api.deepmap.com for example. This can contain a path relative + // to the server, such as https://api.deepmap.com/dev-test, and all the + // paths in the swagger spec will be appended to the server. + Server string + + // Doer for performing requests, typically a *http.Client with any + // customized settings, such as certificate chains. + Client HttpRequestDoer + + // A list of callbacks for modifying requests which are generated before sending over + // the network. + RequestEditors []RequestEditorFn +} + +// ClientOption allows setting custom parameters during construction +type ClientOption func(*Client) error + +// Creates a new Client, with reasonable defaults +func NewClient(server string, opts ...ClientOption) (*Client, error) { + // create a client with sane default values + client := Client{ + Server: server, + } + // mutate client and add all optional params + for _, o := range opts { + if err := o(&client); err != nil { + return nil, err + } + } + // ensure the server URL always has a trailing slash + if !strings.HasSuffix(client.Server, "/") { + client.Server += "/" + } + // create httpClient, if not already present + if client.Client == nil { + client.Client = &http.Client{} + } + return &client, nil +} + +// WithHTTPClient allows overriding the default Doer, which is +// automatically created using http.Client. This is useful for tests. +func WithHTTPClient(doer HttpRequestDoer) ClientOption { + return func(c *Client) error { + c.Client = doer + return nil + } +} + +// WithRequestEditorFn allows setting up a callback function, which will be +// called right before sending the request. This can be used to mutate the request. +func WithRequestEditorFn(fn RequestEditorFn) ClientOption { + return func(c *Client) error { + c.RequestEditors = append(c.RequestEditors, fn) + return nil + } +} + +// The interface specification for the client above. +type ClientInterface interface { + // GetAllSpaces request + GetAllSpaces(ctx context.Context, params *GetAllSpacesParams, reqEditors ...RequestEditorFn) (*http.Response, error) + + // CreateSpaceWithBody request with any body + CreateSpaceWithBody(ctx context.Context, params *CreateSpaceParams, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + CreateSpace(ctx context.Context, params *CreateSpaceParams, body CreateSpaceJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + + // DeleteSpace request + DeleteSpace(ctx context.Context, spaceId SpaceId, params *DeleteSpaceParams, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetSpace request + GetSpace(ctx context.Context, spaceId SpaceId, reqEditors ...RequestEditorFn) (*http.Response, error) + + // UpdateSpaceWithBody request with any body + UpdateSpaceWithBody(ctx context.Context, spaceId SpaceId, params *UpdateSpaceParams, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + UpdateSpace(ctx context.Context, spaceId SpaceId, params *UpdateSpaceParams, body UpdateSpaceJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetAllEnvironments request + GetAllEnvironments(ctx context.Context, spaceId SpaceId, params *GetAllEnvironmentsParams, reqEditors ...RequestEditorFn) (*http.Response, error) + + // CreateEnvironmentWithBody request with any body + CreateEnvironmentWithBody(ctx context.Context, spaceId SpaceId, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + CreateEnvironment(ctx context.Context, spaceId SpaceId, body CreateEnvironmentJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + + // DeleteEnvironment request + DeleteEnvironment(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, params *DeleteEnvironmentParams, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetEnvironment request + GetEnvironment(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, reqEditors ...RequestEditorFn) (*http.Response, error) + + // UpdateEnvironmentWithBody request with any body + UpdateEnvironmentWithBody(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, params *UpdateEnvironmentParams, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + UpdateEnvironment(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, params *UpdateEnvironmentParams, body UpdateEnvironmentJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetAllAssets request + GetAllAssets(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, params *GetAllAssetsParams, reqEditors ...RequestEditorFn) (*http.Response, error) + + // CreateAssetWithBody request with any body + CreateAssetWithBody(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + CreateAsset(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, body CreateAssetJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetAllContentTypes request + GetAllContentTypes(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, params *GetAllContentTypesParams, reqEditors ...RequestEditorFn) (*http.Response, error) + + // CreateContentTypeWithBody request with any body + CreateContentTypeWithBody(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + CreateContentType(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, body CreateContentTypeJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetAllEntries request + GetAllEntries(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, params *GetAllEntriesParams, reqEditors ...RequestEditorFn) (*http.Response, error) + + // CreateEntryWithBody request with any body + CreateEntryWithBody(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, params *CreateEntryParams, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + CreateEntry(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, params *CreateEntryParams, body CreateEntryJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + + // DeleteEntry request + DeleteEntry(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, entryId EntryId, params *DeleteEntryParams, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetEntry request + GetEntry(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, entryId EntryId, reqEditors ...RequestEditorFn) (*http.Response, error) + + // UpdateEntryWithBody request with any body + UpdateEntryWithBody(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, entryId EntryId, params *UpdateEntryParams, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + UpdateEntry(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, entryId EntryId, params *UpdateEntryParams, body UpdateEntryJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + + // UnarchiveEntry request + UnarchiveEntry(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, entryId EntryId, reqEditors ...RequestEditorFn) (*http.Response, error) + + // ArchiveEntry request + ArchiveEntry(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, entryId EntryId, reqEditors ...RequestEditorFn) (*http.Response, error) + + // UnpublishEntry request + UnpublishEntry(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, entryId EntryId, reqEditors ...RequestEditorFn) (*http.Response, error) + + // PublishEntry request + PublishEntry(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, entryId EntryId, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetAllLocales request + GetAllLocales(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, params *GetAllLocalesParams, reqEditors ...RequestEditorFn) (*http.Response, error) + + // CreateLocaleWithBody request with any body + CreateLocaleWithBody(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + CreateLocale(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, body CreateLocaleJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + + // DeleteLocale request + DeleteLocale(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, localeId LocaleId, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetLocale request + GetLocale(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, localeId LocaleId, reqEditors ...RequestEditorFn) (*http.Response, error) + + // UpdateLocaleWithBody request with any body + UpdateLocaleWithBody(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, localeId LocaleId, params *UpdateLocaleParams, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + UpdateLocale(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, localeId LocaleId, params *UpdateLocaleParams, body UpdateLocaleJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetAllWebhooks request + GetAllWebhooks(ctx context.Context, spaceId SpaceId, params *GetAllWebhooksParams, reqEditors ...RequestEditorFn) (*http.Response, error) + + // CreateWebhookWithBody request with any body + CreateWebhookWithBody(ctx context.Context, spaceId SpaceId, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + CreateWebhook(ctx context.Context, spaceId SpaceId, body CreateWebhookJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + + // DeleteWebhook request + DeleteWebhook(ctx context.Context, spaceId SpaceId, webhookId WebhookId, params *DeleteWebhookParams, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GetWebhook request + GetWebhook(ctx context.Context, spaceId SpaceId, webhookId WebhookId, reqEditors ...RequestEditorFn) (*http.Response, error) + + // UpdateWebhookWithBody request with any body + UpdateWebhookWithBody(ctx context.Context, spaceId SpaceId, webhookId WebhookId, params *UpdateWebhookParams, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + UpdateWebhook(ctx context.Context, spaceId SpaceId, webhookId WebhookId, params *UpdateWebhookParams, body UpdateWebhookJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) +} + +func (c *Client) GetAllSpaces(ctx context.Context, params *GetAllSpacesParams, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetAllSpacesRequest(c.Server, params) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) CreateSpaceWithBody(ctx context.Context, params *CreateSpaceParams, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewCreateSpaceRequestWithBody(c.Server, params, contentType, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) CreateSpace(ctx context.Context, params *CreateSpaceParams, body CreateSpaceJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewCreateSpaceRequest(c.Server, params, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) DeleteSpace(ctx context.Context, spaceId SpaceId, params *DeleteSpaceParams, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewDeleteSpaceRequest(c.Server, spaceId, params) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) GetSpace(ctx context.Context, spaceId SpaceId, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetSpaceRequest(c.Server, spaceId) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) UpdateSpaceWithBody(ctx context.Context, spaceId SpaceId, params *UpdateSpaceParams, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewUpdateSpaceRequestWithBody(c.Server, spaceId, params, contentType, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) UpdateSpace(ctx context.Context, spaceId SpaceId, params *UpdateSpaceParams, body UpdateSpaceJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewUpdateSpaceRequest(c.Server, spaceId, params, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) GetAllEnvironments(ctx context.Context, spaceId SpaceId, params *GetAllEnvironmentsParams, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetAllEnvironmentsRequest(c.Server, spaceId, params) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) CreateEnvironmentWithBody(ctx context.Context, spaceId SpaceId, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewCreateEnvironmentRequestWithBody(c.Server, spaceId, contentType, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) CreateEnvironment(ctx context.Context, spaceId SpaceId, body CreateEnvironmentJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewCreateEnvironmentRequest(c.Server, spaceId, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) DeleteEnvironment(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, params *DeleteEnvironmentParams, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewDeleteEnvironmentRequest(c.Server, spaceId, environmentId, params) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) GetEnvironment(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetEnvironmentRequest(c.Server, spaceId, environmentId) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) UpdateEnvironmentWithBody(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, params *UpdateEnvironmentParams, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewUpdateEnvironmentRequestWithBody(c.Server, spaceId, environmentId, params, contentType, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) UpdateEnvironment(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, params *UpdateEnvironmentParams, body UpdateEnvironmentJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewUpdateEnvironmentRequest(c.Server, spaceId, environmentId, params, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) GetAllAssets(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, params *GetAllAssetsParams, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetAllAssetsRequest(c.Server, spaceId, environmentId, params) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) CreateAssetWithBody(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewCreateAssetRequestWithBody(c.Server, spaceId, environmentId, contentType, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) CreateAsset(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, body CreateAssetJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewCreateAssetRequest(c.Server, spaceId, environmentId, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) GetAllContentTypes(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, params *GetAllContentTypesParams, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetAllContentTypesRequest(c.Server, spaceId, environmentId, params) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) CreateContentTypeWithBody(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewCreateContentTypeRequestWithBody(c.Server, spaceId, environmentId, contentType, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) CreateContentType(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, body CreateContentTypeJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewCreateContentTypeRequest(c.Server, spaceId, environmentId, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) GetAllEntries(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, params *GetAllEntriesParams, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetAllEntriesRequest(c.Server, spaceId, environmentId, params) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) CreateEntryWithBody(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, params *CreateEntryParams, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewCreateEntryRequestWithBody(c.Server, spaceId, environmentId, params, contentType, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) CreateEntry(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, params *CreateEntryParams, body CreateEntryJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewCreateEntryRequest(c.Server, spaceId, environmentId, params, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) DeleteEntry(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, entryId EntryId, params *DeleteEntryParams, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewDeleteEntryRequest(c.Server, spaceId, environmentId, entryId, params) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) GetEntry(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, entryId EntryId, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetEntryRequest(c.Server, spaceId, environmentId, entryId) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) UpdateEntryWithBody(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, entryId EntryId, params *UpdateEntryParams, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewUpdateEntryRequestWithBody(c.Server, spaceId, environmentId, entryId, params, contentType, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) UpdateEntry(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, entryId EntryId, params *UpdateEntryParams, body UpdateEntryJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewUpdateEntryRequest(c.Server, spaceId, environmentId, entryId, params, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) UnarchiveEntry(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, entryId EntryId, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewUnarchiveEntryRequest(c.Server, spaceId, environmentId, entryId) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) ArchiveEntry(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, entryId EntryId, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewArchiveEntryRequest(c.Server, spaceId, environmentId, entryId) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) UnpublishEntry(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, entryId EntryId, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewUnpublishEntryRequest(c.Server, spaceId, environmentId, entryId) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) PublishEntry(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, entryId EntryId, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewPublishEntryRequest(c.Server, spaceId, environmentId, entryId) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) GetAllLocales(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, params *GetAllLocalesParams, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetAllLocalesRequest(c.Server, spaceId, environmentId, params) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) CreateLocaleWithBody(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewCreateLocaleRequestWithBody(c.Server, spaceId, environmentId, contentType, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) CreateLocale(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, body CreateLocaleJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewCreateLocaleRequest(c.Server, spaceId, environmentId, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) DeleteLocale(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, localeId LocaleId, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewDeleteLocaleRequest(c.Server, spaceId, environmentId, localeId) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) GetLocale(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, localeId LocaleId, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetLocaleRequest(c.Server, spaceId, environmentId, localeId) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) UpdateLocaleWithBody(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, localeId LocaleId, params *UpdateLocaleParams, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewUpdateLocaleRequestWithBody(c.Server, spaceId, environmentId, localeId, params, contentType, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) UpdateLocale(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, localeId LocaleId, params *UpdateLocaleParams, body UpdateLocaleJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewUpdateLocaleRequest(c.Server, spaceId, environmentId, localeId, params, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) GetAllWebhooks(ctx context.Context, spaceId SpaceId, params *GetAllWebhooksParams, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetAllWebhooksRequest(c.Server, spaceId, params) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) CreateWebhookWithBody(ctx context.Context, spaceId SpaceId, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewCreateWebhookRequestWithBody(c.Server, spaceId, contentType, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) CreateWebhook(ctx context.Context, spaceId SpaceId, body CreateWebhookJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewCreateWebhookRequest(c.Server, spaceId, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) DeleteWebhook(ctx context.Context, spaceId SpaceId, webhookId WebhookId, params *DeleteWebhookParams, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewDeleteWebhookRequest(c.Server, spaceId, webhookId, params) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) GetWebhook(ctx context.Context, spaceId SpaceId, webhookId WebhookId, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetWebhookRequest(c.Server, spaceId, webhookId) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) UpdateWebhookWithBody(ctx context.Context, spaceId SpaceId, webhookId WebhookId, params *UpdateWebhookParams, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewUpdateWebhookRequestWithBody(c.Server, spaceId, webhookId, params, contentType, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) UpdateWebhook(ctx context.Context, spaceId SpaceId, webhookId WebhookId, params *UpdateWebhookParams, body UpdateWebhookJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewUpdateWebhookRequest(c.Server, spaceId, webhookId, params, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +// NewGetAllSpacesRequest generates requests for GetAllSpaces +func NewGetAllSpacesRequest(server string, params *GetAllSpacesParams) (*http.Request, error) { + var err error + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/spaces") + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + if params != nil { + queryValues := queryURL.Query() + + if params.Limit != nil { + + if queryFrag, err := runtime.StyleParamWithLocation("form", true, "limit", runtime.ParamLocationQuery, *params.Limit); err != nil { + return nil, err + } else if parsed, err := url.ParseQuery(queryFrag); err != nil { + return nil, err + } else { + for k, v := range parsed { + for _, v2 := range v { + queryValues.Add(k, v2) + } + } + } + + } + + if params.Skip != nil { + + if queryFrag, err := runtime.StyleParamWithLocation("form", true, "skip", runtime.ParamLocationQuery, *params.Skip); err != nil { + return nil, err + } else if parsed, err := url.ParseQuery(queryFrag); err != nil { + return nil, err + } else { + for k, v := range parsed { + for _, v2 := range v { + queryValues.Add(k, v2) + } + } + } + + } + + queryURL.RawQuery = queryValues.Encode() + } + + req, err := http.NewRequest("GET", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewCreateSpaceRequest calls the generic CreateSpace builder with application/json body +func NewCreateSpaceRequest(server string, params *CreateSpaceParams, body CreateSpaceJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewCreateSpaceRequestWithBody(server, params, "application/json", bodyReader) +} + +// NewCreateSpaceRequestWithBody generates requests for CreateSpace with any type of body +func NewCreateSpaceRequestWithBody(server string, params *CreateSpaceParams, contentType string, body io.Reader) (*http.Request, error) { + var err error + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/spaces") + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("POST", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + if params != nil { + + var headerParam0 string + + headerParam0, err = runtime.StyleParamWithLocation("simple", false, "Content-Type", runtime.ParamLocationHeader, params.ContentType) + if err != nil { + return nil, err + } + + req.Header.Set("Content-Type", headerParam0) + + } + + return req, nil +} + +// NewDeleteSpaceRequest generates requests for DeleteSpace +func NewDeleteSpaceRequest(server string, spaceId SpaceId, params *DeleteSpaceParams) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "spaceId", runtime.ParamLocationPath, spaceId) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/spaces/%s", pathParam0) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("DELETE", queryURL.String(), nil) + if err != nil { + return nil, err + } + + if params != nil { + + var headerParam0 string + + headerParam0, err = runtime.StyleParamWithLocation("simple", false, "X-Contentful-Version", runtime.ParamLocationHeader, params.XContentfulVersion) + if err != nil { + return nil, err + } + + req.Header.Set("X-Contentful-Version", headerParam0) + + } + + return req, nil +} + +// NewGetSpaceRequest generates requests for GetSpace +func NewGetSpaceRequest(server string, spaceId SpaceId) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "spaceId", runtime.ParamLocationPath, spaceId) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/spaces/%s", pathParam0) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("GET", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewUpdateSpaceRequest calls the generic UpdateSpace builder with application/json body +func NewUpdateSpaceRequest(server string, spaceId SpaceId, params *UpdateSpaceParams, body UpdateSpaceJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewUpdateSpaceRequestWithBody(server, spaceId, params, "application/json", bodyReader) +} + +// NewUpdateSpaceRequestWithBody generates requests for UpdateSpace with any type of body +func NewUpdateSpaceRequestWithBody(server string, spaceId SpaceId, params *UpdateSpaceParams, contentType string, body io.Reader) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "spaceId", runtime.ParamLocationPath, spaceId) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/spaces/%s", pathParam0) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("PUT", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + if params != nil { + + var headerParam0 string + + headerParam0, err = runtime.StyleParamWithLocation("simple", false, "X-Contentful-Version", runtime.ParamLocationHeader, params.XContentfulVersion) + if err != nil { + return nil, err + } + + req.Header.Set("X-Contentful-Version", headerParam0) + + } + + return req, nil +} + +// NewGetAllEnvironmentsRequest generates requests for GetAllEnvironments +func NewGetAllEnvironmentsRequest(server string, spaceId SpaceId, params *GetAllEnvironmentsParams) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "spaceId", runtime.ParamLocationPath, spaceId) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/spaces/%s/environments", pathParam0) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + if params != nil { + queryValues := queryURL.Query() + + if params.Limit != nil { + + if queryFrag, err := runtime.StyleParamWithLocation("form", true, "limit", runtime.ParamLocationQuery, *params.Limit); err != nil { + return nil, err + } else if parsed, err := url.ParseQuery(queryFrag); err != nil { + return nil, err + } else { + for k, v := range parsed { + for _, v2 := range v { + queryValues.Add(k, v2) + } + } + } + + } + + if params.Skip != nil { + + if queryFrag, err := runtime.StyleParamWithLocation("form", true, "skip", runtime.ParamLocationQuery, *params.Skip); err != nil { + return nil, err + } else if parsed, err := url.ParseQuery(queryFrag); err != nil { + return nil, err + } else { + for k, v := range parsed { + for _, v2 := range v { + queryValues.Add(k, v2) + } + } + } + + } + + queryURL.RawQuery = queryValues.Encode() + } + + req, err := http.NewRequest("GET", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewCreateEnvironmentRequest calls the generic CreateEnvironment builder with application/json body +func NewCreateEnvironmentRequest(server string, spaceId SpaceId, body CreateEnvironmentJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewCreateEnvironmentRequestWithBody(server, spaceId, "application/json", bodyReader) +} + +// NewCreateEnvironmentRequestWithBody generates requests for CreateEnvironment with any type of body +func NewCreateEnvironmentRequestWithBody(server string, spaceId SpaceId, contentType string, body io.Reader) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "spaceId", runtime.ParamLocationPath, spaceId) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/spaces/%s/environments", pathParam0) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("POST", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + +// NewDeleteEnvironmentRequest generates requests for DeleteEnvironment +func NewDeleteEnvironmentRequest(server string, spaceId SpaceId, environmentId EnvironmentId, params *DeleteEnvironmentParams) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "spaceId", runtime.ParamLocationPath, spaceId) + if err != nil { + return nil, err + } + + var pathParam1 string + + pathParam1, err = runtime.StyleParamWithLocation("simple", false, "environmentId", runtime.ParamLocationPath, environmentId) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/spaces/%s/environments/%s", pathParam0, pathParam1) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("DELETE", queryURL.String(), nil) + if err != nil { + return nil, err + } + + if params != nil { + + var headerParam0 string + + headerParam0, err = runtime.StyleParamWithLocation("simple", false, "X-Contentful-Version", runtime.ParamLocationHeader, params.XContentfulVersion) + if err != nil { + return nil, err + } + + req.Header.Set("X-Contentful-Version", headerParam0) + + } + + return req, nil +} + +// NewGetEnvironmentRequest generates requests for GetEnvironment +func NewGetEnvironmentRequest(server string, spaceId SpaceId, environmentId EnvironmentId) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "spaceId", runtime.ParamLocationPath, spaceId) + if err != nil { + return nil, err + } + + var pathParam1 string + + pathParam1, err = runtime.StyleParamWithLocation("simple", false, "environmentId", runtime.ParamLocationPath, environmentId) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/spaces/%s/environments/%s", pathParam0, pathParam1) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("GET", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewUpdateEnvironmentRequest calls the generic UpdateEnvironment builder with application/json body +func NewUpdateEnvironmentRequest(server string, spaceId SpaceId, environmentId EnvironmentId, params *UpdateEnvironmentParams, body UpdateEnvironmentJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewUpdateEnvironmentRequestWithBody(server, spaceId, environmentId, params, "application/json", bodyReader) +} + +// NewUpdateEnvironmentRequestWithBody generates requests for UpdateEnvironment with any type of body +func NewUpdateEnvironmentRequestWithBody(server string, spaceId SpaceId, environmentId EnvironmentId, params *UpdateEnvironmentParams, contentType string, body io.Reader) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "spaceId", runtime.ParamLocationPath, spaceId) + if err != nil { + return nil, err + } + + var pathParam1 string + + pathParam1, err = runtime.StyleParamWithLocation("simple", false, "environmentId", runtime.ParamLocationPath, environmentId) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/spaces/%s/environments/%s", pathParam0, pathParam1) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("PUT", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + if params != nil { + + var headerParam0 string + + headerParam0, err = runtime.StyleParamWithLocation("simple", false, "X-Contentful-Version", runtime.ParamLocationHeader, params.XContentfulVersion) + if err != nil { + return nil, err + } + + req.Header.Set("X-Contentful-Version", headerParam0) + + } + + return req, nil +} + +// NewGetAllAssetsRequest generates requests for GetAllAssets +func NewGetAllAssetsRequest(server string, spaceId SpaceId, environmentId EnvironmentId, params *GetAllAssetsParams) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "spaceId", runtime.ParamLocationPath, spaceId) + if err != nil { + return nil, err + } + + var pathParam1 string + + pathParam1, err = runtime.StyleParamWithLocation("simple", false, "environmentId", runtime.ParamLocationPath, environmentId) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/spaces/%s/environments/%s/assets", pathParam0, pathParam1) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + if params != nil { + queryValues := queryURL.Query() + + if params.Limit != nil { + + if queryFrag, err := runtime.StyleParamWithLocation("form", true, "limit", runtime.ParamLocationQuery, *params.Limit); err != nil { + return nil, err + } else if parsed, err := url.ParseQuery(queryFrag); err != nil { + return nil, err + } else { + for k, v := range parsed { + for _, v2 := range v { + queryValues.Add(k, v2) + } + } + } + + } + + if params.Skip != nil { + + if queryFrag, err := runtime.StyleParamWithLocation("form", true, "skip", runtime.ParamLocationQuery, *params.Skip); err != nil { + return nil, err + } else if parsed, err := url.ParseQuery(queryFrag); err != nil { + return nil, err + } else { + for k, v := range parsed { + for _, v2 := range v { + queryValues.Add(k, v2) + } + } + } + + } + + queryURL.RawQuery = queryValues.Encode() + } + + req, err := http.NewRequest("GET", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewCreateAssetRequest calls the generic CreateAsset builder with application/json body +func NewCreateAssetRequest(server string, spaceId SpaceId, environmentId EnvironmentId, body CreateAssetJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewCreateAssetRequestWithBody(server, spaceId, environmentId, "application/json", bodyReader) +} + +// NewCreateAssetRequestWithBody generates requests for CreateAsset with any type of body +func NewCreateAssetRequestWithBody(server string, spaceId SpaceId, environmentId EnvironmentId, contentType string, body io.Reader) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "spaceId", runtime.ParamLocationPath, spaceId) + if err != nil { + return nil, err + } + + var pathParam1 string + + pathParam1, err = runtime.StyleParamWithLocation("simple", false, "environmentId", runtime.ParamLocationPath, environmentId) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/spaces/%s/environments/%s/assets", pathParam0, pathParam1) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("POST", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + +// NewGetAllContentTypesRequest generates requests for GetAllContentTypes +func NewGetAllContentTypesRequest(server string, spaceId SpaceId, environmentId EnvironmentId, params *GetAllContentTypesParams) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "spaceId", runtime.ParamLocationPath, spaceId) + if err != nil { + return nil, err + } + + var pathParam1 string + + pathParam1, err = runtime.StyleParamWithLocation("simple", false, "environmentId", runtime.ParamLocationPath, environmentId) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/spaces/%s/environments/%s/content_types", pathParam0, pathParam1) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + if params != nil { + queryValues := queryURL.Query() + + if params.Limit != nil { + + if queryFrag, err := runtime.StyleParamWithLocation("form", true, "limit", runtime.ParamLocationQuery, *params.Limit); err != nil { + return nil, err + } else if parsed, err := url.ParseQuery(queryFrag); err != nil { + return nil, err + } else { + for k, v := range parsed { + for _, v2 := range v { + queryValues.Add(k, v2) + } + } + } + + } + + if params.Skip != nil { + + if queryFrag, err := runtime.StyleParamWithLocation("form", true, "skip", runtime.ParamLocationQuery, *params.Skip); err != nil { + return nil, err + } else if parsed, err := url.ParseQuery(queryFrag); err != nil { + return nil, err + } else { + for k, v := range parsed { + for _, v2 := range v { + queryValues.Add(k, v2) + } + } + } + + } + + queryURL.RawQuery = queryValues.Encode() + } + + req, err := http.NewRequest("GET", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewCreateContentTypeRequest calls the generic CreateContentType builder with application/json body +func NewCreateContentTypeRequest(server string, spaceId SpaceId, environmentId EnvironmentId, body CreateContentTypeJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewCreateContentTypeRequestWithBody(server, spaceId, environmentId, "application/json", bodyReader) +} + +// NewCreateContentTypeRequestWithBody generates requests for CreateContentType with any type of body +func NewCreateContentTypeRequestWithBody(server string, spaceId SpaceId, environmentId EnvironmentId, contentType string, body io.Reader) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "spaceId", runtime.ParamLocationPath, spaceId) + if err != nil { + return nil, err + } + + var pathParam1 string + + pathParam1, err = runtime.StyleParamWithLocation("simple", false, "environmentId", runtime.ParamLocationPath, environmentId) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/spaces/%s/environments/%s/content_types", pathParam0, pathParam1) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("POST", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + +// NewGetAllEntriesRequest generates requests for GetAllEntries +func NewGetAllEntriesRequest(server string, spaceId SpaceId, environmentId EnvironmentId, params *GetAllEntriesParams) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "spaceId", runtime.ParamLocationPath, spaceId) + if err != nil { + return nil, err + } + + var pathParam1 string + + pathParam1, err = runtime.StyleParamWithLocation("simple", false, "environmentId", runtime.ParamLocationPath, environmentId) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/spaces/%s/environments/%s/entries", pathParam0, pathParam1) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + if params != nil { + queryValues := queryURL.Query() + + if params.Limit != nil { + + if queryFrag, err := runtime.StyleParamWithLocation("form", true, "limit", runtime.ParamLocationQuery, *params.Limit); err != nil { + return nil, err + } else if parsed, err := url.ParseQuery(queryFrag); err != nil { + return nil, err + } else { + for k, v := range parsed { + for _, v2 := range v { + queryValues.Add(k, v2) + } + } + } + + } + + if params.Skip != nil { + + if queryFrag, err := runtime.StyleParamWithLocation("form", true, "skip", runtime.ParamLocationQuery, *params.Skip); err != nil { + return nil, err + } else if parsed, err := url.ParseQuery(queryFrag); err != nil { + return nil, err + } else { + for k, v := range parsed { + for _, v2 := range v { + queryValues.Add(k, v2) + } + } + } + + } + + if params.ContentType != nil { + + if queryFrag, err := runtime.StyleParamWithLocation("form", true, "content_type", runtime.ParamLocationQuery, *params.ContentType); err != nil { + return nil, err + } else if parsed, err := url.ParseQuery(queryFrag); err != nil { + return nil, err + } else { + for k, v := range parsed { + for _, v2 := range v { + queryValues.Add(k, v2) + } + } + } + + } + + queryURL.RawQuery = queryValues.Encode() + } + + req, err := http.NewRequest("GET", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewCreateEntryRequest calls the generic CreateEntry builder with application/json body +func NewCreateEntryRequest(server string, spaceId SpaceId, environmentId EnvironmentId, params *CreateEntryParams, body CreateEntryJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewCreateEntryRequestWithBody(server, spaceId, environmentId, params, "application/json", bodyReader) +} + +// NewCreateEntryRequestWithBody generates requests for CreateEntry with any type of body +func NewCreateEntryRequestWithBody(server string, spaceId SpaceId, environmentId EnvironmentId, params *CreateEntryParams, contentType string, body io.Reader) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "spaceId", runtime.ParamLocationPath, spaceId) + if err != nil { + return nil, err + } + + var pathParam1 string + + pathParam1, err = runtime.StyleParamWithLocation("simple", false, "environmentId", runtime.ParamLocationPath, environmentId) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/spaces/%s/environments/%s/entries", pathParam0, pathParam1) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + if params != nil { + queryValues := queryURL.Query() + + if queryFrag, err := runtime.StyleParamWithLocation("form", true, "content_type", runtime.ParamLocationQuery, params.ContentType); err != nil { + return nil, err + } else if parsed, err := url.ParseQuery(queryFrag); err != nil { + return nil, err + } else { + for k, v := range parsed { + for _, v2 := range v { + queryValues.Add(k, v2) + } + } + } + + queryURL.RawQuery = queryValues.Encode() + } + + req, err := http.NewRequest("POST", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + +// NewDeleteEntryRequest generates requests for DeleteEntry +func NewDeleteEntryRequest(server string, spaceId SpaceId, environmentId EnvironmentId, entryId EntryId, params *DeleteEntryParams) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "spaceId", runtime.ParamLocationPath, spaceId) + if err != nil { + return nil, err + } + + var pathParam1 string + + pathParam1, err = runtime.StyleParamWithLocation("simple", false, "environmentId", runtime.ParamLocationPath, environmentId) + if err != nil { + return nil, err + } + + var pathParam2 string + + pathParam2, err = runtime.StyleParamWithLocation("simple", false, "entryId", runtime.ParamLocationPath, entryId) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/spaces/%s/environments/%s/entries/%s", pathParam0, pathParam1, pathParam2) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("DELETE", queryURL.String(), nil) + if err != nil { + return nil, err + } + + if params != nil { + + var headerParam0 string + + headerParam0, err = runtime.StyleParamWithLocation("simple", false, "X-Contentful-Version", runtime.ParamLocationHeader, params.XContentfulVersion) + if err != nil { + return nil, err + } + + req.Header.Set("X-Contentful-Version", headerParam0) + + } + + return req, nil +} + +// NewGetEntryRequest generates requests for GetEntry +func NewGetEntryRequest(server string, spaceId SpaceId, environmentId EnvironmentId, entryId EntryId) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "spaceId", runtime.ParamLocationPath, spaceId) + if err != nil { + return nil, err + } + + var pathParam1 string + + pathParam1, err = runtime.StyleParamWithLocation("simple", false, "environmentId", runtime.ParamLocationPath, environmentId) + if err != nil { + return nil, err + } + + var pathParam2 string + + pathParam2, err = runtime.StyleParamWithLocation("simple", false, "entryId", runtime.ParamLocationPath, entryId) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/spaces/%s/environments/%s/entries/%s", pathParam0, pathParam1, pathParam2) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("GET", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewUpdateEntryRequest calls the generic UpdateEntry builder with application/json body +func NewUpdateEntryRequest(server string, spaceId SpaceId, environmentId EnvironmentId, entryId EntryId, params *UpdateEntryParams, body UpdateEntryJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewUpdateEntryRequestWithBody(server, spaceId, environmentId, entryId, params, "application/json", bodyReader) +} + +// NewUpdateEntryRequestWithBody generates requests for UpdateEntry with any type of body +func NewUpdateEntryRequestWithBody(server string, spaceId SpaceId, environmentId EnvironmentId, entryId EntryId, params *UpdateEntryParams, contentType string, body io.Reader) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "spaceId", runtime.ParamLocationPath, spaceId) + if err != nil { + return nil, err + } + + var pathParam1 string + + pathParam1, err = runtime.StyleParamWithLocation("simple", false, "environmentId", runtime.ParamLocationPath, environmentId) + if err != nil { + return nil, err + } + + var pathParam2 string + + pathParam2, err = runtime.StyleParamWithLocation("simple", false, "entryId", runtime.ParamLocationPath, entryId) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/spaces/%s/environments/%s/entries/%s", pathParam0, pathParam1, pathParam2) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("PUT", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + if params != nil { + + var headerParam0 string + + headerParam0, err = runtime.StyleParamWithLocation("simple", false, "X-Contentful-Version", runtime.ParamLocationHeader, params.XContentfulVersion) + if err != nil { + return nil, err + } + + req.Header.Set("X-Contentful-Version", headerParam0) + + } + + return req, nil +} + +// NewUnarchiveEntryRequest generates requests for UnarchiveEntry +func NewUnarchiveEntryRequest(server string, spaceId SpaceId, environmentId EnvironmentId, entryId EntryId) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "spaceId", runtime.ParamLocationPath, spaceId) + if err != nil { + return nil, err + } + + var pathParam1 string + + pathParam1, err = runtime.StyleParamWithLocation("simple", false, "environmentId", runtime.ParamLocationPath, environmentId) + if err != nil { + return nil, err + } + + var pathParam2 string + + pathParam2, err = runtime.StyleParamWithLocation("simple", false, "entryId", runtime.ParamLocationPath, entryId) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/spaces/%s/environments/%s/entries/%s/archived", pathParam0, pathParam1, pathParam2) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("DELETE", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewArchiveEntryRequest generates requests for ArchiveEntry +func NewArchiveEntryRequest(server string, spaceId SpaceId, environmentId EnvironmentId, entryId EntryId) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "spaceId", runtime.ParamLocationPath, spaceId) + if err != nil { + return nil, err + } + + var pathParam1 string + + pathParam1, err = runtime.StyleParamWithLocation("simple", false, "environmentId", runtime.ParamLocationPath, environmentId) + if err != nil { + return nil, err + } + + var pathParam2 string + + pathParam2, err = runtime.StyleParamWithLocation("simple", false, "entryId", runtime.ParamLocationPath, entryId) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/spaces/%s/environments/%s/entries/%s/archived", pathParam0, pathParam1, pathParam2) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("PUT", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewUnpublishEntryRequest generates requests for UnpublishEntry +func NewUnpublishEntryRequest(server string, spaceId SpaceId, environmentId EnvironmentId, entryId EntryId) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "spaceId", runtime.ParamLocationPath, spaceId) + if err != nil { + return nil, err + } + + var pathParam1 string + + pathParam1, err = runtime.StyleParamWithLocation("simple", false, "environmentId", runtime.ParamLocationPath, environmentId) + if err != nil { + return nil, err + } + + var pathParam2 string + + pathParam2, err = runtime.StyleParamWithLocation("simple", false, "entryId", runtime.ParamLocationPath, entryId) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/spaces/%s/environments/%s/entries/%s/published", pathParam0, pathParam1, pathParam2) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("DELETE", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewPublishEntryRequest generates requests for PublishEntry +func NewPublishEntryRequest(server string, spaceId SpaceId, environmentId EnvironmentId, entryId EntryId) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "spaceId", runtime.ParamLocationPath, spaceId) + if err != nil { + return nil, err + } + + var pathParam1 string + + pathParam1, err = runtime.StyleParamWithLocation("simple", false, "environmentId", runtime.ParamLocationPath, environmentId) + if err != nil { + return nil, err + } + + var pathParam2 string + + pathParam2, err = runtime.StyleParamWithLocation("simple", false, "entryId", runtime.ParamLocationPath, entryId) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/spaces/%s/environments/%s/entries/%s/published", pathParam0, pathParam1, pathParam2) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("PUT", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewGetAllLocalesRequest generates requests for GetAllLocales +func NewGetAllLocalesRequest(server string, spaceId SpaceId, environmentId EnvironmentId, params *GetAllLocalesParams) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "spaceId", runtime.ParamLocationPath, spaceId) + if err != nil { + return nil, err + } + + var pathParam1 string + + pathParam1, err = runtime.StyleParamWithLocation("simple", false, "environmentId", runtime.ParamLocationPath, environmentId) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/spaces/%s/environments/%s/locales", pathParam0, pathParam1) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + if params != nil { + queryValues := queryURL.Query() + + if params.Limit != nil { + + if queryFrag, err := runtime.StyleParamWithLocation("form", true, "limit", runtime.ParamLocationQuery, *params.Limit); err != nil { + return nil, err + } else if parsed, err := url.ParseQuery(queryFrag); err != nil { + return nil, err + } else { + for k, v := range parsed { + for _, v2 := range v { + queryValues.Add(k, v2) + } + } + } + + } + + if params.Skip != nil { + + if queryFrag, err := runtime.StyleParamWithLocation("form", true, "skip", runtime.ParamLocationQuery, *params.Skip); err != nil { + return nil, err + } else if parsed, err := url.ParseQuery(queryFrag); err != nil { + return nil, err + } else { + for k, v := range parsed { + for _, v2 := range v { + queryValues.Add(k, v2) + } + } + } + + } + + queryURL.RawQuery = queryValues.Encode() + } + + req, err := http.NewRequest("GET", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewCreateLocaleRequest calls the generic CreateLocale builder with application/json body +func NewCreateLocaleRequest(server string, spaceId SpaceId, environmentId EnvironmentId, body CreateLocaleJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewCreateLocaleRequestWithBody(server, spaceId, environmentId, "application/json", bodyReader) +} + +// NewCreateLocaleRequestWithBody generates requests for CreateLocale with any type of body +func NewCreateLocaleRequestWithBody(server string, spaceId SpaceId, environmentId EnvironmentId, contentType string, body io.Reader) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "spaceId", runtime.ParamLocationPath, spaceId) + if err != nil { + return nil, err + } + + var pathParam1 string + + pathParam1, err = runtime.StyleParamWithLocation("simple", false, "environmentId", runtime.ParamLocationPath, environmentId) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/spaces/%s/environments/%s/locales", pathParam0, pathParam1) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("POST", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + +// NewDeleteLocaleRequest generates requests for DeleteLocale +func NewDeleteLocaleRequest(server string, spaceId SpaceId, environmentId EnvironmentId, localeId LocaleId) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "spaceId", runtime.ParamLocationPath, spaceId) + if err != nil { + return nil, err + } + + var pathParam1 string + + pathParam1, err = runtime.StyleParamWithLocation("simple", false, "environmentId", runtime.ParamLocationPath, environmentId) + if err != nil { + return nil, err + } + + var pathParam2 string + + pathParam2, err = runtime.StyleParamWithLocation("simple", false, "localeId", runtime.ParamLocationPath, localeId) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/spaces/%s/environments/%s/locales/%s", pathParam0, pathParam1, pathParam2) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("DELETE", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewGetLocaleRequest generates requests for GetLocale +func NewGetLocaleRequest(server string, spaceId SpaceId, environmentId EnvironmentId, localeId LocaleId) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "spaceId", runtime.ParamLocationPath, spaceId) + if err != nil { + return nil, err + } + + var pathParam1 string + + pathParam1, err = runtime.StyleParamWithLocation("simple", false, "environmentId", runtime.ParamLocationPath, environmentId) + if err != nil { + return nil, err + } + + var pathParam2 string + + pathParam2, err = runtime.StyleParamWithLocation("simple", false, "localeId", runtime.ParamLocationPath, localeId) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/spaces/%s/environments/%s/locales/%s", pathParam0, pathParam1, pathParam2) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("GET", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewUpdateLocaleRequest calls the generic UpdateLocale builder with application/json body +func NewUpdateLocaleRequest(server string, spaceId SpaceId, environmentId EnvironmentId, localeId LocaleId, params *UpdateLocaleParams, body UpdateLocaleJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewUpdateLocaleRequestWithBody(server, spaceId, environmentId, localeId, params, "application/json", bodyReader) +} + +// NewUpdateLocaleRequestWithBody generates requests for UpdateLocale with any type of body +func NewUpdateLocaleRequestWithBody(server string, spaceId SpaceId, environmentId EnvironmentId, localeId LocaleId, params *UpdateLocaleParams, contentType string, body io.Reader) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "spaceId", runtime.ParamLocationPath, spaceId) + if err != nil { + return nil, err + } + + var pathParam1 string + + pathParam1, err = runtime.StyleParamWithLocation("simple", false, "environmentId", runtime.ParamLocationPath, environmentId) + if err != nil { + return nil, err + } + + var pathParam2 string + + pathParam2, err = runtime.StyleParamWithLocation("simple", false, "localeId", runtime.ParamLocationPath, localeId) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/spaces/%s/environments/%s/locales/%s", pathParam0, pathParam1, pathParam2) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("PUT", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + if params != nil { + + var headerParam0 string + + headerParam0, err = runtime.StyleParamWithLocation("simple", false, "X-Contentful-Version", runtime.ParamLocationHeader, params.XContentfulVersion) + if err != nil { + return nil, err + } + + req.Header.Set("X-Contentful-Version", headerParam0) + + } + + return req, nil +} + +// NewGetAllWebhooksRequest generates requests for GetAllWebhooks +func NewGetAllWebhooksRequest(server string, spaceId SpaceId, params *GetAllWebhooksParams) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "spaceId", runtime.ParamLocationPath, spaceId) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/spaces/%s/webhook_definitions", pathParam0) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + if params != nil { + queryValues := queryURL.Query() + + if params.Limit != nil { + + if queryFrag, err := runtime.StyleParamWithLocation("form", true, "limit", runtime.ParamLocationQuery, *params.Limit); err != nil { + return nil, err + } else if parsed, err := url.ParseQuery(queryFrag); err != nil { + return nil, err + } else { + for k, v := range parsed { + for _, v2 := range v { + queryValues.Add(k, v2) + } + } + } + + } + + if params.Skip != nil { + + if queryFrag, err := runtime.StyleParamWithLocation("form", true, "skip", runtime.ParamLocationQuery, *params.Skip); err != nil { + return nil, err + } else if parsed, err := url.ParseQuery(queryFrag); err != nil { + return nil, err + } else { + for k, v := range parsed { + for _, v2 := range v { + queryValues.Add(k, v2) + } + } + } + + } + + queryURL.RawQuery = queryValues.Encode() + } + + req, err := http.NewRequest("GET", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewCreateWebhookRequest calls the generic CreateWebhook builder with application/json body +func NewCreateWebhookRequest(server string, spaceId SpaceId, body CreateWebhookJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewCreateWebhookRequestWithBody(server, spaceId, "application/json", bodyReader) +} + +// NewCreateWebhookRequestWithBody generates requests for CreateWebhook with any type of body +func NewCreateWebhookRequestWithBody(server string, spaceId SpaceId, contentType string, body io.Reader) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "spaceId", runtime.ParamLocationPath, spaceId) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/spaces/%s/webhook_definitions", pathParam0) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("POST", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + +// NewDeleteWebhookRequest generates requests for DeleteWebhook +func NewDeleteWebhookRequest(server string, spaceId SpaceId, webhookId WebhookId, params *DeleteWebhookParams) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "spaceId", runtime.ParamLocationPath, spaceId) + if err != nil { + return nil, err + } + + var pathParam1 string + + pathParam1, err = runtime.StyleParamWithLocation("simple", false, "webhookId", runtime.ParamLocationPath, webhookId) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/spaces/%s/webhook_definitions/%s", pathParam0, pathParam1) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("DELETE", queryURL.String(), nil) + if err != nil { + return nil, err + } + + if params != nil { + + var headerParam0 string + + headerParam0, err = runtime.StyleParamWithLocation("simple", false, "X-Contentful-Version", runtime.ParamLocationHeader, params.XContentfulVersion) + if err != nil { + return nil, err + } + + req.Header.Set("X-Contentful-Version", headerParam0) + + } + + return req, nil +} + +// NewGetWebhookRequest generates requests for GetWebhook +func NewGetWebhookRequest(server string, spaceId SpaceId, webhookId WebhookId) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "spaceId", runtime.ParamLocationPath, spaceId) + if err != nil { + return nil, err + } + + var pathParam1 string + + pathParam1, err = runtime.StyleParamWithLocation("simple", false, "webhookId", runtime.ParamLocationPath, webhookId) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/spaces/%s/webhook_definitions/%s", pathParam0, pathParam1) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("GET", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewUpdateWebhookRequest calls the generic UpdateWebhook builder with application/json body +func NewUpdateWebhookRequest(server string, spaceId SpaceId, webhookId WebhookId, params *UpdateWebhookParams, body UpdateWebhookJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewUpdateWebhookRequestWithBody(server, spaceId, webhookId, params, "application/json", bodyReader) +} + +// NewUpdateWebhookRequestWithBody generates requests for UpdateWebhook with any type of body +func NewUpdateWebhookRequestWithBody(server string, spaceId SpaceId, webhookId WebhookId, params *UpdateWebhookParams, contentType string, body io.Reader) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "spaceId", runtime.ParamLocationPath, spaceId) + if err != nil { + return nil, err + } + + var pathParam1 string + + pathParam1, err = runtime.StyleParamWithLocation("simple", false, "webhookId", runtime.ParamLocationPath, webhookId) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/spaces/%s/webhook_definitions/%s", pathParam0, pathParam1) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("PUT", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + if params != nil { + + var headerParam0 string + + headerParam0, err = runtime.StyleParamWithLocation("simple", false, "X-Contentful-Version", runtime.ParamLocationHeader, params.XContentfulVersion) + if err != nil { + return nil, err + } + + req.Header.Set("X-Contentful-Version", headerParam0) + + } + + return req, nil +} + +func (c *Client) applyEditors(ctx context.Context, req *http.Request, additionalEditors []RequestEditorFn) error { + for _, r := range c.RequestEditors { + if err := r(ctx, req); err != nil { + return err + } + } + for _, r := range additionalEditors { + if err := r(ctx, req); err != nil { + return err + } + } + return nil +} + +// ClientWithResponses builds on ClientInterface to offer response payloads +type ClientWithResponses struct { + ClientInterface +} + +// NewClientWithResponses creates a new ClientWithResponses, which wraps +// Client with return type handling +func NewClientWithResponses(server string, opts ...ClientOption) (*ClientWithResponses, error) { + client, err := NewClient(server, opts...) + if err != nil { + return nil, err + } + return &ClientWithResponses{client}, nil +} + +// WithBaseURL overrides the baseURL. +func WithBaseURL(baseURL string) ClientOption { + return func(c *Client) error { + newBaseURL, err := url.Parse(baseURL) + if err != nil { + return err + } + c.Server = newBaseURL.String() + return nil + } +} + +// ClientWithResponsesInterface is the interface specification for the client with responses above. +type ClientWithResponsesInterface interface { + // GetAllSpacesWithResponse request + GetAllSpacesWithResponse(ctx context.Context, params *GetAllSpacesParams, reqEditors ...RequestEditorFn) (*GetAllSpacesResponse, error) + + // CreateSpaceWithBodyWithResponse request with any body + CreateSpaceWithBodyWithResponse(ctx context.Context, params *CreateSpaceParams, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*CreateSpaceResponse, error) + + CreateSpaceWithResponse(ctx context.Context, params *CreateSpaceParams, body CreateSpaceJSONRequestBody, reqEditors ...RequestEditorFn) (*CreateSpaceResponse, error) + + // DeleteSpaceWithResponse request + DeleteSpaceWithResponse(ctx context.Context, spaceId SpaceId, params *DeleteSpaceParams, reqEditors ...RequestEditorFn) (*DeleteSpaceResponse, error) + + // GetSpaceWithResponse request + GetSpaceWithResponse(ctx context.Context, spaceId SpaceId, reqEditors ...RequestEditorFn) (*GetSpaceResponse, error) + + // UpdateSpaceWithBodyWithResponse request with any body + UpdateSpaceWithBodyWithResponse(ctx context.Context, spaceId SpaceId, params *UpdateSpaceParams, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*UpdateSpaceResponse, error) + + UpdateSpaceWithResponse(ctx context.Context, spaceId SpaceId, params *UpdateSpaceParams, body UpdateSpaceJSONRequestBody, reqEditors ...RequestEditorFn) (*UpdateSpaceResponse, error) + + // GetAllEnvironmentsWithResponse request + GetAllEnvironmentsWithResponse(ctx context.Context, spaceId SpaceId, params *GetAllEnvironmentsParams, reqEditors ...RequestEditorFn) (*GetAllEnvironmentsResponse, error) + + // CreateEnvironmentWithBodyWithResponse request with any body + CreateEnvironmentWithBodyWithResponse(ctx context.Context, spaceId SpaceId, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*CreateEnvironmentResponse, error) + + CreateEnvironmentWithResponse(ctx context.Context, spaceId SpaceId, body CreateEnvironmentJSONRequestBody, reqEditors ...RequestEditorFn) (*CreateEnvironmentResponse, error) + + // DeleteEnvironmentWithResponse request + DeleteEnvironmentWithResponse(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, params *DeleteEnvironmentParams, reqEditors ...RequestEditorFn) (*DeleteEnvironmentResponse, error) + + // GetEnvironmentWithResponse request + GetEnvironmentWithResponse(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, reqEditors ...RequestEditorFn) (*GetEnvironmentResponse, error) + + // UpdateEnvironmentWithBodyWithResponse request with any body + UpdateEnvironmentWithBodyWithResponse(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, params *UpdateEnvironmentParams, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*UpdateEnvironmentResponse, error) + + UpdateEnvironmentWithResponse(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, params *UpdateEnvironmentParams, body UpdateEnvironmentJSONRequestBody, reqEditors ...RequestEditorFn) (*UpdateEnvironmentResponse, error) + + // GetAllAssetsWithResponse request + GetAllAssetsWithResponse(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, params *GetAllAssetsParams, reqEditors ...RequestEditorFn) (*GetAllAssetsResponse, error) + + // CreateAssetWithBodyWithResponse request with any body + CreateAssetWithBodyWithResponse(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*CreateAssetResponse, error) + + CreateAssetWithResponse(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, body CreateAssetJSONRequestBody, reqEditors ...RequestEditorFn) (*CreateAssetResponse, error) + + // GetAllContentTypesWithResponse request + GetAllContentTypesWithResponse(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, params *GetAllContentTypesParams, reqEditors ...RequestEditorFn) (*GetAllContentTypesResponse, error) + + // CreateContentTypeWithBodyWithResponse request with any body + CreateContentTypeWithBodyWithResponse(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*CreateContentTypeResponse, error) + + CreateContentTypeWithResponse(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, body CreateContentTypeJSONRequestBody, reqEditors ...RequestEditorFn) (*CreateContentTypeResponse, error) + + // GetAllEntriesWithResponse request + GetAllEntriesWithResponse(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, params *GetAllEntriesParams, reqEditors ...RequestEditorFn) (*GetAllEntriesResponse, error) + + // CreateEntryWithBodyWithResponse request with any body + CreateEntryWithBodyWithResponse(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, params *CreateEntryParams, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*CreateEntryResponse, error) + + CreateEntryWithResponse(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, params *CreateEntryParams, body CreateEntryJSONRequestBody, reqEditors ...RequestEditorFn) (*CreateEntryResponse, error) + + // DeleteEntryWithResponse request + DeleteEntryWithResponse(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, entryId EntryId, params *DeleteEntryParams, reqEditors ...RequestEditorFn) (*DeleteEntryResponse, error) + + // GetEntryWithResponse request + GetEntryWithResponse(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, entryId EntryId, reqEditors ...RequestEditorFn) (*GetEntryResponse, error) + + // UpdateEntryWithBodyWithResponse request with any body + UpdateEntryWithBodyWithResponse(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, entryId EntryId, params *UpdateEntryParams, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*UpdateEntryResponse, error) + + UpdateEntryWithResponse(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, entryId EntryId, params *UpdateEntryParams, body UpdateEntryJSONRequestBody, reqEditors ...RequestEditorFn) (*UpdateEntryResponse, error) + + // UnarchiveEntryWithResponse request + UnarchiveEntryWithResponse(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, entryId EntryId, reqEditors ...RequestEditorFn) (*UnarchiveEntryResponse, error) + + // ArchiveEntryWithResponse request + ArchiveEntryWithResponse(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, entryId EntryId, reqEditors ...RequestEditorFn) (*ArchiveEntryResponse, error) + + // UnpublishEntryWithResponse request + UnpublishEntryWithResponse(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, entryId EntryId, reqEditors ...RequestEditorFn) (*UnpublishEntryResponse, error) + + // PublishEntryWithResponse request + PublishEntryWithResponse(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, entryId EntryId, reqEditors ...RequestEditorFn) (*PublishEntryResponse, error) + + // GetAllLocalesWithResponse request + GetAllLocalesWithResponse(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, params *GetAllLocalesParams, reqEditors ...RequestEditorFn) (*GetAllLocalesResponse, error) + + // CreateLocaleWithBodyWithResponse request with any body + CreateLocaleWithBodyWithResponse(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*CreateLocaleResponse, error) + + CreateLocaleWithResponse(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, body CreateLocaleJSONRequestBody, reqEditors ...RequestEditorFn) (*CreateLocaleResponse, error) + + // DeleteLocaleWithResponse request + DeleteLocaleWithResponse(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, localeId LocaleId, reqEditors ...RequestEditorFn) (*DeleteLocaleResponse, error) + + // GetLocaleWithResponse request + GetLocaleWithResponse(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, localeId LocaleId, reqEditors ...RequestEditorFn) (*GetLocaleResponse, error) + + // UpdateLocaleWithBodyWithResponse request with any body + UpdateLocaleWithBodyWithResponse(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, localeId LocaleId, params *UpdateLocaleParams, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*UpdateLocaleResponse, error) + + UpdateLocaleWithResponse(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, localeId LocaleId, params *UpdateLocaleParams, body UpdateLocaleJSONRequestBody, reqEditors ...RequestEditorFn) (*UpdateLocaleResponse, error) + + // GetAllWebhooksWithResponse request + GetAllWebhooksWithResponse(ctx context.Context, spaceId SpaceId, params *GetAllWebhooksParams, reqEditors ...RequestEditorFn) (*GetAllWebhooksResponse, error) + + // CreateWebhookWithBodyWithResponse request with any body + CreateWebhookWithBodyWithResponse(ctx context.Context, spaceId SpaceId, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*CreateWebhookResponse, error) + + CreateWebhookWithResponse(ctx context.Context, spaceId SpaceId, body CreateWebhookJSONRequestBody, reqEditors ...RequestEditorFn) (*CreateWebhookResponse, error) + + // DeleteWebhookWithResponse request + DeleteWebhookWithResponse(ctx context.Context, spaceId SpaceId, webhookId WebhookId, params *DeleteWebhookParams, reqEditors ...RequestEditorFn) (*DeleteWebhookResponse, error) + + // GetWebhookWithResponse request + GetWebhookWithResponse(ctx context.Context, spaceId SpaceId, webhookId WebhookId, reqEditors ...RequestEditorFn) (*GetWebhookResponse, error) + + // UpdateWebhookWithBodyWithResponse request with any body + UpdateWebhookWithBodyWithResponse(ctx context.Context, spaceId SpaceId, webhookId WebhookId, params *UpdateWebhookParams, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*UpdateWebhookResponse, error) + + UpdateWebhookWithResponse(ctx context.Context, spaceId SpaceId, webhookId WebhookId, params *UpdateWebhookParams, body UpdateWebhookJSONRequestBody, reqEditors ...RequestEditorFn) (*UpdateWebhookResponse, error) +} + +type GetAllSpacesResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *SpaceCollection +} + +// Status returns HTTPResponse.Status +func (r GetAllSpacesResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetAllSpacesResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type CreateSpaceResponse struct { + Body []byte + HTTPResponse *http.Response + JSON201 *Space +} + +// Status returns HTTPResponse.Status +func (r CreateSpaceResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r CreateSpaceResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type DeleteSpaceResponse struct { + Body []byte + HTTPResponse *http.Response +} + +// Status returns HTTPResponse.Status +func (r DeleteSpaceResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r DeleteSpaceResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type GetSpaceResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *Space +} + +// Status returns HTTPResponse.Status +func (r GetSpaceResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetSpaceResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type UpdateSpaceResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *Space +} + +// Status returns HTTPResponse.Status +func (r UpdateSpaceResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r UpdateSpaceResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type GetAllEnvironmentsResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *EnvironmentCollection +} + +// Status returns HTTPResponse.Status +func (r GetAllEnvironmentsResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetAllEnvironmentsResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type CreateEnvironmentResponse struct { + Body []byte + HTTPResponse *http.Response + JSON201 *Environment +} + +// Status returns HTTPResponse.Status +func (r CreateEnvironmentResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r CreateEnvironmentResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type DeleteEnvironmentResponse struct { + Body []byte + HTTPResponse *http.Response +} + +// Status returns HTTPResponse.Status +func (r DeleteEnvironmentResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r DeleteEnvironmentResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type GetEnvironmentResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *Environment +} + +// Status returns HTTPResponse.Status +func (r GetEnvironmentResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetEnvironmentResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type UpdateEnvironmentResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *Environment +} + +// Status returns HTTPResponse.Status +func (r UpdateEnvironmentResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r UpdateEnvironmentResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type GetAllAssetsResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *AssetCollection +} + +// Status returns HTTPResponse.Status +func (r GetAllAssetsResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetAllAssetsResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type CreateAssetResponse struct { + Body []byte + HTTPResponse *http.Response + JSON201 *Asset +} + +// Status returns HTTPResponse.Status +func (r CreateAssetResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r CreateAssetResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type GetAllContentTypesResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *ContentTypeCollection +} + +// Status returns HTTPResponse.Status +func (r GetAllContentTypesResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetAllContentTypesResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type CreateContentTypeResponse struct { + Body []byte + HTTPResponse *http.Response + JSON201 *ContentType +} + +// Status returns HTTPResponse.Status +func (r CreateContentTypeResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r CreateContentTypeResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type GetAllEntriesResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *EntryCollection +} + +// Status returns HTTPResponse.Status +func (r GetAllEntriesResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetAllEntriesResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type CreateEntryResponse struct { + Body []byte + HTTPResponse *http.Response + JSON201 *Entry +} + +// Status returns HTTPResponse.Status +func (r CreateEntryResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r CreateEntryResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type DeleteEntryResponse struct { + Body []byte + HTTPResponse *http.Response +} + +// Status returns HTTPResponse.Status +func (r DeleteEntryResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r DeleteEntryResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type GetEntryResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *Entry +} + +// Status returns HTTPResponse.Status +func (r GetEntryResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetEntryResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type UpdateEntryResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *Entry +} + +// Status returns HTTPResponse.Status +func (r UpdateEntryResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r UpdateEntryResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type UnarchiveEntryResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *Entry +} + +// Status returns HTTPResponse.Status +func (r UnarchiveEntryResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r UnarchiveEntryResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type ArchiveEntryResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *Entry +} + +// Status returns HTTPResponse.Status +func (r ArchiveEntryResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r ArchiveEntryResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type UnpublishEntryResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *Entry +} + +// Status returns HTTPResponse.Status +func (r UnpublishEntryResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r UnpublishEntryResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type PublishEntryResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *Entry +} + +// Status returns HTTPResponse.Status +func (r PublishEntryResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r PublishEntryResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type GetAllLocalesResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *LocaleCollection +} + +// Status returns HTTPResponse.Status +func (r GetAllLocalesResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetAllLocalesResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type CreateLocaleResponse struct { + Body []byte + HTTPResponse *http.Response + JSON201 *Locale +} + +// Status returns HTTPResponse.Status +func (r CreateLocaleResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r CreateLocaleResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type DeleteLocaleResponse struct { + Body []byte + HTTPResponse *http.Response +} + +// Status returns HTTPResponse.Status +func (r DeleteLocaleResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r DeleteLocaleResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type GetLocaleResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *Locale +} + +// Status returns HTTPResponse.Status +func (r GetLocaleResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetLocaleResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type UpdateLocaleResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *Locale +} + +// Status returns HTTPResponse.Status +func (r UpdateLocaleResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r UpdateLocaleResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type GetAllWebhooksResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *WebhookCollection +} + +// Status returns HTTPResponse.Status +func (r GetAllWebhooksResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetAllWebhooksResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type CreateWebhookResponse struct { + Body []byte + HTTPResponse *http.Response + JSON201 *Webhook +} + +// Status returns HTTPResponse.Status +func (r CreateWebhookResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r CreateWebhookResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type DeleteWebhookResponse struct { + Body []byte + HTTPResponse *http.Response +} + +// Status returns HTTPResponse.Status +func (r DeleteWebhookResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r DeleteWebhookResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type GetWebhookResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *Webhook +} + +// Status returns HTTPResponse.Status +func (r GetWebhookResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetWebhookResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type UpdateWebhookResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *Webhook +} + +// Status returns HTTPResponse.Status +func (r UpdateWebhookResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r UpdateWebhookResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +// GetAllSpacesWithResponse request returning *GetAllSpacesResponse +func (c *ClientWithResponses) GetAllSpacesWithResponse(ctx context.Context, params *GetAllSpacesParams, reqEditors ...RequestEditorFn) (*GetAllSpacesResponse, error) { + rsp, err := c.GetAllSpaces(ctx, params, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetAllSpacesResponse(rsp) +} + +// CreateSpaceWithBodyWithResponse request with arbitrary body returning *CreateSpaceResponse +func (c *ClientWithResponses) CreateSpaceWithBodyWithResponse(ctx context.Context, params *CreateSpaceParams, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*CreateSpaceResponse, error) { + rsp, err := c.CreateSpaceWithBody(ctx, params, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseCreateSpaceResponse(rsp) +} + +func (c *ClientWithResponses) CreateSpaceWithResponse(ctx context.Context, params *CreateSpaceParams, body CreateSpaceJSONRequestBody, reqEditors ...RequestEditorFn) (*CreateSpaceResponse, error) { + rsp, err := c.CreateSpace(ctx, params, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseCreateSpaceResponse(rsp) +} + +// DeleteSpaceWithResponse request returning *DeleteSpaceResponse +func (c *ClientWithResponses) DeleteSpaceWithResponse(ctx context.Context, spaceId SpaceId, params *DeleteSpaceParams, reqEditors ...RequestEditorFn) (*DeleteSpaceResponse, error) { + rsp, err := c.DeleteSpace(ctx, spaceId, params, reqEditors...) + if err != nil { + return nil, err + } + return ParseDeleteSpaceResponse(rsp) +} + +// GetSpaceWithResponse request returning *GetSpaceResponse +func (c *ClientWithResponses) GetSpaceWithResponse(ctx context.Context, spaceId SpaceId, reqEditors ...RequestEditorFn) (*GetSpaceResponse, error) { + rsp, err := c.GetSpace(ctx, spaceId, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetSpaceResponse(rsp) +} + +// UpdateSpaceWithBodyWithResponse request with arbitrary body returning *UpdateSpaceResponse +func (c *ClientWithResponses) UpdateSpaceWithBodyWithResponse(ctx context.Context, spaceId SpaceId, params *UpdateSpaceParams, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*UpdateSpaceResponse, error) { + rsp, err := c.UpdateSpaceWithBody(ctx, spaceId, params, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseUpdateSpaceResponse(rsp) +} + +func (c *ClientWithResponses) UpdateSpaceWithResponse(ctx context.Context, spaceId SpaceId, params *UpdateSpaceParams, body UpdateSpaceJSONRequestBody, reqEditors ...RequestEditorFn) (*UpdateSpaceResponse, error) { + rsp, err := c.UpdateSpace(ctx, spaceId, params, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseUpdateSpaceResponse(rsp) +} + +// GetAllEnvironmentsWithResponse request returning *GetAllEnvironmentsResponse +func (c *ClientWithResponses) GetAllEnvironmentsWithResponse(ctx context.Context, spaceId SpaceId, params *GetAllEnvironmentsParams, reqEditors ...RequestEditorFn) (*GetAllEnvironmentsResponse, error) { + rsp, err := c.GetAllEnvironments(ctx, spaceId, params, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetAllEnvironmentsResponse(rsp) +} + +// CreateEnvironmentWithBodyWithResponse request with arbitrary body returning *CreateEnvironmentResponse +func (c *ClientWithResponses) CreateEnvironmentWithBodyWithResponse(ctx context.Context, spaceId SpaceId, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*CreateEnvironmentResponse, error) { + rsp, err := c.CreateEnvironmentWithBody(ctx, spaceId, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseCreateEnvironmentResponse(rsp) +} + +func (c *ClientWithResponses) CreateEnvironmentWithResponse(ctx context.Context, spaceId SpaceId, body CreateEnvironmentJSONRequestBody, reqEditors ...RequestEditorFn) (*CreateEnvironmentResponse, error) { + rsp, err := c.CreateEnvironment(ctx, spaceId, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseCreateEnvironmentResponse(rsp) +} + +// DeleteEnvironmentWithResponse request returning *DeleteEnvironmentResponse +func (c *ClientWithResponses) DeleteEnvironmentWithResponse(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, params *DeleteEnvironmentParams, reqEditors ...RequestEditorFn) (*DeleteEnvironmentResponse, error) { + rsp, err := c.DeleteEnvironment(ctx, spaceId, environmentId, params, reqEditors...) + if err != nil { + return nil, err + } + return ParseDeleteEnvironmentResponse(rsp) +} + +// GetEnvironmentWithResponse request returning *GetEnvironmentResponse +func (c *ClientWithResponses) GetEnvironmentWithResponse(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, reqEditors ...RequestEditorFn) (*GetEnvironmentResponse, error) { + rsp, err := c.GetEnvironment(ctx, spaceId, environmentId, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetEnvironmentResponse(rsp) +} + +// UpdateEnvironmentWithBodyWithResponse request with arbitrary body returning *UpdateEnvironmentResponse +func (c *ClientWithResponses) UpdateEnvironmentWithBodyWithResponse(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, params *UpdateEnvironmentParams, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*UpdateEnvironmentResponse, error) { + rsp, err := c.UpdateEnvironmentWithBody(ctx, spaceId, environmentId, params, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseUpdateEnvironmentResponse(rsp) +} + +func (c *ClientWithResponses) UpdateEnvironmentWithResponse(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, params *UpdateEnvironmentParams, body UpdateEnvironmentJSONRequestBody, reqEditors ...RequestEditorFn) (*UpdateEnvironmentResponse, error) { + rsp, err := c.UpdateEnvironment(ctx, spaceId, environmentId, params, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseUpdateEnvironmentResponse(rsp) +} + +// GetAllAssetsWithResponse request returning *GetAllAssetsResponse +func (c *ClientWithResponses) GetAllAssetsWithResponse(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, params *GetAllAssetsParams, reqEditors ...RequestEditorFn) (*GetAllAssetsResponse, error) { + rsp, err := c.GetAllAssets(ctx, spaceId, environmentId, params, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetAllAssetsResponse(rsp) +} + +// CreateAssetWithBodyWithResponse request with arbitrary body returning *CreateAssetResponse +func (c *ClientWithResponses) CreateAssetWithBodyWithResponse(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*CreateAssetResponse, error) { + rsp, err := c.CreateAssetWithBody(ctx, spaceId, environmentId, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseCreateAssetResponse(rsp) +} + +func (c *ClientWithResponses) CreateAssetWithResponse(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, body CreateAssetJSONRequestBody, reqEditors ...RequestEditorFn) (*CreateAssetResponse, error) { + rsp, err := c.CreateAsset(ctx, spaceId, environmentId, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseCreateAssetResponse(rsp) +} + +// GetAllContentTypesWithResponse request returning *GetAllContentTypesResponse +func (c *ClientWithResponses) GetAllContentTypesWithResponse(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, params *GetAllContentTypesParams, reqEditors ...RequestEditorFn) (*GetAllContentTypesResponse, error) { + rsp, err := c.GetAllContentTypes(ctx, spaceId, environmentId, params, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetAllContentTypesResponse(rsp) +} + +// CreateContentTypeWithBodyWithResponse request with arbitrary body returning *CreateContentTypeResponse +func (c *ClientWithResponses) CreateContentTypeWithBodyWithResponse(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*CreateContentTypeResponse, error) { + rsp, err := c.CreateContentTypeWithBody(ctx, spaceId, environmentId, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseCreateContentTypeResponse(rsp) +} + +func (c *ClientWithResponses) CreateContentTypeWithResponse(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, body CreateContentTypeJSONRequestBody, reqEditors ...RequestEditorFn) (*CreateContentTypeResponse, error) { + rsp, err := c.CreateContentType(ctx, spaceId, environmentId, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseCreateContentTypeResponse(rsp) +} + +// GetAllEntriesWithResponse request returning *GetAllEntriesResponse +func (c *ClientWithResponses) GetAllEntriesWithResponse(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, params *GetAllEntriesParams, reqEditors ...RequestEditorFn) (*GetAllEntriesResponse, error) { + rsp, err := c.GetAllEntries(ctx, spaceId, environmentId, params, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetAllEntriesResponse(rsp) +} + +// CreateEntryWithBodyWithResponse request with arbitrary body returning *CreateEntryResponse +func (c *ClientWithResponses) CreateEntryWithBodyWithResponse(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, params *CreateEntryParams, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*CreateEntryResponse, error) { + rsp, err := c.CreateEntryWithBody(ctx, spaceId, environmentId, params, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseCreateEntryResponse(rsp) +} + +func (c *ClientWithResponses) CreateEntryWithResponse(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, params *CreateEntryParams, body CreateEntryJSONRequestBody, reqEditors ...RequestEditorFn) (*CreateEntryResponse, error) { + rsp, err := c.CreateEntry(ctx, spaceId, environmentId, params, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseCreateEntryResponse(rsp) +} + +// DeleteEntryWithResponse request returning *DeleteEntryResponse +func (c *ClientWithResponses) DeleteEntryWithResponse(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, entryId EntryId, params *DeleteEntryParams, reqEditors ...RequestEditorFn) (*DeleteEntryResponse, error) { + rsp, err := c.DeleteEntry(ctx, spaceId, environmentId, entryId, params, reqEditors...) + if err != nil { + return nil, err + } + return ParseDeleteEntryResponse(rsp) +} + +// GetEntryWithResponse request returning *GetEntryResponse +func (c *ClientWithResponses) GetEntryWithResponse(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, entryId EntryId, reqEditors ...RequestEditorFn) (*GetEntryResponse, error) { + rsp, err := c.GetEntry(ctx, spaceId, environmentId, entryId, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetEntryResponse(rsp) +} + +// UpdateEntryWithBodyWithResponse request with arbitrary body returning *UpdateEntryResponse +func (c *ClientWithResponses) UpdateEntryWithBodyWithResponse(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, entryId EntryId, params *UpdateEntryParams, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*UpdateEntryResponse, error) { + rsp, err := c.UpdateEntryWithBody(ctx, spaceId, environmentId, entryId, params, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseUpdateEntryResponse(rsp) +} + +func (c *ClientWithResponses) UpdateEntryWithResponse(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, entryId EntryId, params *UpdateEntryParams, body UpdateEntryJSONRequestBody, reqEditors ...RequestEditorFn) (*UpdateEntryResponse, error) { + rsp, err := c.UpdateEntry(ctx, spaceId, environmentId, entryId, params, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseUpdateEntryResponse(rsp) +} + +// UnarchiveEntryWithResponse request returning *UnarchiveEntryResponse +func (c *ClientWithResponses) UnarchiveEntryWithResponse(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, entryId EntryId, reqEditors ...RequestEditorFn) (*UnarchiveEntryResponse, error) { + rsp, err := c.UnarchiveEntry(ctx, spaceId, environmentId, entryId, reqEditors...) + if err != nil { + return nil, err + } + return ParseUnarchiveEntryResponse(rsp) +} + +// ArchiveEntryWithResponse request returning *ArchiveEntryResponse +func (c *ClientWithResponses) ArchiveEntryWithResponse(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, entryId EntryId, reqEditors ...RequestEditorFn) (*ArchiveEntryResponse, error) { + rsp, err := c.ArchiveEntry(ctx, spaceId, environmentId, entryId, reqEditors...) + if err != nil { + return nil, err + } + return ParseArchiveEntryResponse(rsp) +} + +// UnpublishEntryWithResponse request returning *UnpublishEntryResponse +func (c *ClientWithResponses) UnpublishEntryWithResponse(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, entryId EntryId, reqEditors ...RequestEditorFn) (*UnpublishEntryResponse, error) { + rsp, err := c.UnpublishEntry(ctx, spaceId, environmentId, entryId, reqEditors...) + if err != nil { + return nil, err + } + return ParseUnpublishEntryResponse(rsp) +} + +// PublishEntryWithResponse request returning *PublishEntryResponse +func (c *ClientWithResponses) PublishEntryWithResponse(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, entryId EntryId, reqEditors ...RequestEditorFn) (*PublishEntryResponse, error) { + rsp, err := c.PublishEntry(ctx, spaceId, environmentId, entryId, reqEditors...) + if err != nil { + return nil, err + } + return ParsePublishEntryResponse(rsp) +} + +// GetAllLocalesWithResponse request returning *GetAllLocalesResponse +func (c *ClientWithResponses) GetAllLocalesWithResponse(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, params *GetAllLocalesParams, reqEditors ...RequestEditorFn) (*GetAllLocalesResponse, error) { + rsp, err := c.GetAllLocales(ctx, spaceId, environmentId, params, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetAllLocalesResponse(rsp) +} + +// CreateLocaleWithBodyWithResponse request with arbitrary body returning *CreateLocaleResponse +func (c *ClientWithResponses) CreateLocaleWithBodyWithResponse(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*CreateLocaleResponse, error) { + rsp, err := c.CreateLocaleWithBody(ctx, spaceId, environmentId, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseCreateLocaleResponse(rsp) +} + +func (c *ClientWithResponses) CreateLocaleWithResponse(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, body CreateLocaleJSONRequestBody, reqEditors ...RequestEditorFn) (*CreateLocaleResponse, error) { + rsp, err := c.CreateLocale(ctx, spaceId, environmentId, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseCreateLocaleResponse(rsp) +} + +// DeleteLocaleWithResponse request returning *DeleteLocaleResponse +func (c *ClientWithResponses) DeleteLocaleWithResponse(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, localeId LocaleId, reqEditors ...RequestEditorFn) (*DeleteLocaleResponse, error) { + rsp, err := c.DeleteLocale(ctx, spaceId, environmentId, localeId, reqEditors...) + if err != nil { + return nil, err + } + return ParseDeleteLocaleResponse(rsp) +} + +// GetLocaleWithResponse request returning *GetLocaleResponse +func (c *ClientWithResponses) GetLocaleWithResponse(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, localeId LocaleId, reqEditors ...RequestEditorFn) (*GetLocaleResponse, error) { + rsp, err := c.GetLocale(ctx, spaceId, environmentId, localeId, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetLocaleResponse(rsp) +} + +// UpdateLocaleWithBodyWithResponse request with arbitrary body returning *UpdateLocaleResponse +func (c *ClientWithResponses) UpdateLocaleWithBodyWithResponse(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, localeId LocaleId, params *UpdateLocaleParams, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*UpdateLocaleResponse, error) { + rsp, err := c.UpdateLocaleWithBody(ctx, spaceId, environmentId, localeId, params, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseUpdateLocaleResponse(rsp) +} + +func (c *ClientWithResponses) UpdateLocaleWithResponse(ctx context.Context, spaceId SpaceId, environmentId EnvironmentId, localeId LocaleId, params *UpdateLocaleParams, body UpdateLocaleJSONRequestBody, reqEditors ...RequestEditorFn) (*UpdateLocaleResponse, error) { + rsp, err := c.UpdateLocale(ctx, spaceId, environmentId, localeId, params, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseUpdateLocaleResponse(rsp) +} + +// GetAllWebhooksWithResponse request returning *GetAllWebhooksResponse +func (c *ClientWithResponses) GetAllWebhooksWithResponse(ctx context.Context, spaceId SpaceId, params *GetAllWebhooksParams, reqEditors ...RequestEditorFn) (*GetAllWebhooksResponse, error) { + rsp, err := c.GetAllWebhooks(ctx, spaceId, params, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetAllWebhooksResponse(rsp) +} + +// CreateWebhookWithBodyWithResponse request with arbitrary body returning *CreateWebhookResponse +func (c *ClientWithResponses) CreateWebhookWithBodyWithResponse(ctx context.Context, spaceId SpaceId, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*CreateWebhookResponse, error) { + rsp, err := c.CreateWebhookWithBody(ctx, spaceId, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseCreateWebhookResponse(rsp) +} + +func (c *ClientWithResponses) CreateWebhookWithResponse(ctx context.Context, spaceId SpaceId, body CreateWebhookJSONRequestBody, reqEditors ...RequestEditorFn) (*CreateWebhookResponse, error) { + rsp, err := c.CreateWebhook(ctx, spaceId, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseCreateWebhookResponse(rsp) +} + +// DeleteWebhookWithResponse request returning *DeleteWebhookResponse +func (c *ClientWithResponses) DeleteWebhookWithResponse(ctx context.Context, spaceId SpaceId, webhookId WebhookId, params *DeleteWebhookParams, reqEditors ...RequestEditorFn) (*DeleteWebhookResponse, error) { + rsp, err := c.DeleteWebhook(ctx, spaceId, webhookId, params, reqEditors...) + if err != nil { + return nil, err + } + return ParseDeleteWebhookResponse(rsp) +} + +// GetWebhookWithResponse request returning *GetWebhookResponse +func (c *ClientWithResponses) GetWebhookWithResponse(ctx context.Context, spaceId SpaceId, webhookId WebhookId, reqEditors ...RequestEditorFn) (*GetWebhookResponse, error) { + rsp, err := c.GetWebhook(ctx, spaceId, webhookId, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetWebhookResponse(rsp) +} + +// UpdateWebhookWithBodyWithResponse request with arbitrary body returning *UpdateWebhookResponse +func (c *ClientWithResponses) UpdateWebhookWithBodyWithResponse(ctx context.Context, spaceId SpaceId, webhookId WebhookId, params *UpdateWebhookParams, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*UpdateWebhookResponse, error) { + rsp, err := c.UpdateWebhookWithBody(ctx, spaceId, webhookId, params, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseUpdateWebhookResponse(rsp) +} + +func (c *ClientWithResponses) UpdateWebhookWithResponse(ctx context.Context, spaceId SpaceId, webhookId WebhookId, params *UpdateWebhookParams, body UpdateWebhookJSONRequestBody, reqEditors ...RequestEditorFn) (*UpdateWebhookResponse, error) { + rsp, err := c.UpdateWebhook(ctx, spaceId, webhookId, params, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseUpdateWebhookResponse(rsp) +} + +// ParseGetAllSpacesResponse parses an HTTP response from a GetAllSpacesWithResponse call +func ParseGetAllSpacesResponse(rsp *http.Response) (*GetAllSpacesResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetAllSpacesResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest SpaceCollection + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} + +// ParseCreateSpaceResponse parses an HTTP response from a CreateSpaceWithResponse call +func ParseCreateSpaceResponse(rsp *http.Response) (*CreateSpaceResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &CreateSpaceResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 201: + var dest Space + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON201 = &dest + + } + + return response, nil +} + +// ParseDeleteSpaceResponse parses an HTTP response from a DeleteSpaceWithResponse call +func ParseDeleteSpaceResponse(rsp *http.Response) (*DeleteSpaceResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &DeleteSpaceResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + return response, nil +} + +// ParseGetSpaceResponse parses an HTTP response from a GetSpaceWithResponse call +func ParseGetSpaceResponse(rsp *http.Response) (*GetSpaceResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetSpaceResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest Space + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} + +// ParseUpdateSpaceResponse parses an HTTP response from a UpdateSpaceWithResponse call +func ParseUpdateSpaceResponse(rsp *http.Response) (*UpdateSpaceResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &UpdateSpaceResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest Space + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} + +// ParseGetAllEnvironmentsResponse parses an HTTP response from a GetAllEnvironmentsWithResponse call +func ParseGetAllEnvironmentsResponse(rsp *http.Response) (*GetAllEnvironmentsResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetAllEnvironmentsResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest EnvironmentCollection + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} + +// ParseCreateEnvironmentResponse parses an HTTP response from a CreateEnvironmentWithResponse call +func ParseCreateEnvironmentResponse(rsp *http.Response) (*CreateEnvironmentResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &CreateEnvironmentResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 201: + var dest Environment + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON201 = &dest + + } + + return response, nil +} + +// ParseDeleteEnvironmentResponse parses an HTTP response from a DeleteEnvironmentWithResponse call +func ParseDeleteEnvironmentResponse(rsp *http.Response) (*DeleteEnvironmentResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &DeleteEnvironmentResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + return response, nil +} + +// ParseGetEnvironmentResponse parses an HTTP response from a GetEnvironmentWithResponse call +func ParseGetEnvironmentResponse(rsp *http.Response) (*GetEnvironmentResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetEnvironmentResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest Environment + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} + +// ParseUpdateEnvironmentResponse parses an HTTP response from a UpdateEnvironmentWithResponse call +func ParseUpdateEnvironmentResponse(rsp *http.Response) (*UpdateEnvironmentResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &UpdateEnvironmentResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest Environment + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} + +// ParseGetAllAssetsResponse parses an HTTP response from a GetAllAssetsWithResponse call +func ParseGetAllAssetsResponse(rsp *http.Response) (*GetAllAssetsResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetAllAssetsResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest AssetCollection + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} + +// ParseCreateAssetResponse parses an HTTP response from a CreateAssetWithResponse call +func ParseCreateAssetResponse(rsp *http.Response) (*CreateAssetResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &CreateAssetResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 201: + var dest Asset + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON201 = &dest + + } + + return response, nil +} + +// ParseGetAllContentTypesResponse parses an HTTP response from a GetAllContentTypesWithResponse call +func ParseGetAllContentTypesResponse(rsp *http.Response) (*GetAllContentTypesResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetAllContentTypesResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest ContentTypeCollection + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} + +// ParseCreateContentTypeResponse parses an HTTP response from a CreateContentTypeWithResponse call +func ParseCreateContentTypeResponse(rsp *http.Response) (*CreateContentTypeResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &CreateContentTypeResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 201: + var dest ContentType + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON201 = &dest + + } + + return response, nil +} + +// ParseGetAllEntriesResponse parses an HTTP response from a GetAllEntriesWithResponse call +func ParseGetAllEntriesResponse(rsp *http.Response) (*GetAllEntriesResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetAllEntriesResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest EntryCollection + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} + +// ParseCreateEntryResponse parses an HTTP response from a CreateEntryWithResponse call +func ParseCreateEntryResponse(rsp *http.Response) (*CreateEntryResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &CreateEntryResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 201: + var dest Entry + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON201 = &dest + + } + + return response, nil +} + +// ParseDeleteEntryResponse parses an HTTP response from a DeleteEntryWithResponse call +func ParseDeleteEntryResponse(rsp *http.Response) (*DeleteEntryResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &DeleteEntryResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + return response, nil +} + +// ParseGetEntryResponse parses an HTTP response from a GetEntryWithResponse call +func ParseGetEntryResponse(rsp *http.Response) (*GetEntryResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetEntryResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest Entry + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} + +// ParseUpdateEntryResponse parses an HTTP response from a UpdateEntryWithResponse call +func ParseUpdateEntryResponse(rsp *http.Response) (*UpdateEntryResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &UpdateEntryResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest Entry + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} + +// ParseUnarchiveEntryResponse parses an HTTP response from a UnarchiveEntryWithResponse call +func ParseUnarchiveEntryResponse(rsp *http.Response) (*UnarchiveEntryResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &UnarchiveEntryResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest Entry + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} + +// ParseArchiveEntryResponse parses an HTTP response from a ArchiveEntryWithResponse call +func ParseArchiveEntryResponse(rsp *http.Response) (*ArchiveEntryResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &ArchiveEntryResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest Entry + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} + +// ParseUnpublishEntryResponse parses an HTTP response from a UnpublishEntryWithResponse call +func ParseUnpublishEntryResponse(rsp *http.Response) (*UnpublishEntryResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &UnpublishEntryResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest Entry + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} + +// ParsePublishEntryResponse parses an HTTP response from a PublishEntryWithResponse call +func ParsePublishEntryResponse(rsp *http.Response) (*PublishEntryResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &PublishEntryResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest Entry + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} + +// ParseGetAllLocalesResponse parses an HTTP response from a GetAllLocalesWithResponse call +func ParseGetAllLocalesResponse(rsp *http.Response) (*GetAllLocalesResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetAllLocalesResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest LocaleCollection + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} + +// ParseCreateLocaleResponse parses an HTTP response from a CreateLocaleWithResponse call +func ParseCreateLocaleResponse(rsp *http.Response) (*CreateLocaleResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &CreateLocaleResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 201: + var dest Locale + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON201 = &dest + + } + + return response, nil +} + +// ParseDeleteLocaleResponse parses an HTTP response from a DeleteLocaleWithResponse call +func ParseDeleteLocaleResponse(rsp *http.Response) (*DeleteLocaleResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &DeleteLocaleResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + return response, nil +} + +// ParseGetLocaleResponse parses an HTTP response from a GetLocaleWithResponse call +func ParseGetLocaleResponse(rsp *http.Response) (*GetLocaleResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetLocaleResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest Locale + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} + +// ParseUpdateLocaleResponse parses an HTTP response from a UpdateLocaleWithResponse call +func ParseUpdateLocaleResponse(rsp *http.Response) (*UpdateLocaleResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &UpdateLocaleResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest Locale + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} + +// ParseGetAllWebhooksResponse parses an HTTP response from a GetAllWebhooksWithResponse call +func ParseGetAllWebhooksResponse(rsp *http.Response) (*GetAllWebhooksResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetAllWebhooksResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest WebhookCollection + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} + +// ParseCreateWebhookResponse parses an HTTP response from a CreateWebhookWithResponse call +func ParseCreateWebhookResponse(rsp *http.Response) (*CreateWebhookResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &CreateWebhookResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 201: + var dest Webhook + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON201 = &dest + + } + + return response, nil +} + +// ParseDeleteWebhookResponse parses an HTTP response from a DeleteWebhookWithResponse call +func ParseDeleteWebhookResponse(rsp *http.Response) (*DeleteWebhookResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &DeleteWebhookResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + return response, nil +} + +// ParseGetWebhookResponse parses an HTTP response from a GetWebhookWithResponse call +func ParseGetWebhookResponse(rsp *http.Response) (*GetWebhookResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetWebhookResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest Webhook + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} + +// ParseUpdateWebhookResponse parses an HTTP response from a UpdateWebhookWithResponse call +func ParseUpdateWebhookResponse(rsp *http.Response) (*UpdateWebhookResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &UpdateWebhookResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest Webhook + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} diff --git a/internal/utils/container.go b/internal/utils/container.go index d09b2ba..f785826 100644 --- a/internal/utils/container.go +++ b/internal/utils/container.go @@ -3,10 +3,13 @@ package utils import ( "github.com/labd/contentful-go" "github.com/labd/contentful-go/service/cma" + + "github.com/labd/terraform-provider-contentful/internal/sdk" ) type ProviderData struct { - Client *contentful.Client + Client *sdk.ClientWithResponses + ClientOld *contentful.Client CMAClient cma.SpaceIdClientBuilder OrganizationId string } diff --git a/internal/utils/http_debug.go b/internal/utils/http_debug.go new file mode 100644 index 0000000..2528c4f --- /dev/null +++ b/internal/utils/http_debug.go @@ -0,0 +1,63 @@ +package utils + +import ( + "context" + "fmt" + "net/http" + "net/http/httputil" + + "github.com/hashicorp/terraform-plugin-log/tflog" +) + +func NewDebugTransport(innerTransport http.RoundTripper) http.RoundTripper { + return &LogTransport{ + transport: innerTransport, + } +} + +type LogTransport struct { + transport http.RoundTripper +} + +var DebugTransport = &LogTransport{ + transport: http.DefaultTransport, +} + +func (c *LogTransport) RoundTrip(request *http.Request) (*http.Response, error) { + logRequest(request.Context(), request) + response, err := c.transport.RoundTrip(request) + logResponse(request.Context(), response, err) + return response, err +} + +const logRequestTemplate = `DEBUG: +---[ REQUEST ]-------------------------------------------------------- +%s +---------------------------------------------------------------------- +` + +const logResponseTemplate = `DEBUG: +---[ RESPONSE ]------------------------------------------------------- +%s +---------------------------------------------------------------------- +` + +func logRequest(ctx context.Context, r *http.Request) { + body, err := httputil.DumpRequestOut(r, true) + if err != nil { + return + } + tflog.Debug(ctx, fmt.Sprintf(logRequestTemplate, body)) +} + +func logResponse(ctx context.Context, r *http.Response, err error) { + if err != nil { + tflog.Debug(ctx, fmt.Sprintf(logResponseTemplate, err)) + return + } + body, err := httputil.DumpResponse(r, true) + if err != nil { + return + } + tflog.Debug(ctx, fmt.Sprintf(logResponseTemplate, body)) +} diff --git a/internal/utils/types.go b/internal/utils/types.go index 0ff2e0a..3c1aeb1 100644 --- a/internal/utils/types.go +++ b/internal/utils/types.go @@ -26,3 +26,7 @@ func GetAppFieldTypes() []string { func GetLinkTypes() []string { return []string{"Asset", "Entry"} } + +func Pointer[T any](v T) *T { + return &v +} diff --git a/oapi-config.yaml b/oapi-config.yaml new file mode 100644 index 0000000..b8382d8 --- /dev/null +++ b/oapi-config.yaml @@ -0,0 +1,7 @@ +package: sdk +generate: + models: true + client: true +output: internal/sdk/main.gen.go +output-options: + skip-prune: true diff --git a/openapi.yaml b/openapi.yaml new file mode 100644 index 0000000..f92e36a --- /dev/null +++ b/openapi.yaml @@ -0,0 +1,1307 @@ +openapi: 3.0.3 +info: + title: Contentful Content Management API + description: | + The Contentful Content Management API (CMA) is a RESTful API for managing content in Contentful. + It allows you to create, update, delete and retrieve content from your Contentful spaces. + version: "1.0.0" + contact: + name: Contentful Support + url: https://www.contentful.com/support/ + +servers: + - url: https://api.contentful.com + description: Contentful Content Management API + +security: + - bearerAuth: [] + +paths: + /spaces: + get: + summary: Get all spaces + description: Retrieves all spaces the authorized user has access to + operationId: getAllSpaces + parameters: + - $ref: "#/components/parameters/limit" + - $ref: "#/components/parameters/skip" + responses: + "200": + description: Success + content: + application/json: + schema: + $ref: "#/components/schemas/SpaceCollection" + post: + summary: Create a space + description: Creates a new space + operationId: createSpace + parameters: + - $ref: "#/components/parameters/contentTypeHeader" + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/SpaceCreate" + responses: + "201": + description: Created + content: + application/json: + schema: + $ref: "#/components/schemas/Space" + + /spaces/{spaceId}: + parameters: + - $ref: "#/components/parameters/spaceId" + get: + summary: Get a space + description: Retrieves a specific space by ID + operationId: getSpace + responses: + "200": + description: Success + content: + application/json: + schema: + $ref: "#/components/schemas/Space" + put: + summary: Update a space + description: Updates a space + operationId: updateSpace + parameters: + - $ref: "#/components/parameters/resourceVersion" + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/SpaceUpdate" + responses: + "200": + description: Success + content: + application/json: + schema: + $ref: "#/components/schemas/Space" + delete: + summary: Delete a space + description: Deletes a space + operationId: deleteSpace + parameters: + - $ref: "#/components/parameters/resourceVersion" + responses: + "204": + description: No Content + + /spaces/{spaceId}/environments: + parameters: + - $ref: "#/components/parameters/spaceId" + get: + summary: Get all environments + description: Retrieves all environments in a space + operationId: getAllEnvironments + parameters: + - $ref: "#/components/parameters/limit" + - $ref: "#/components/parameters/skip" + responses: + "200": + description: Success + content: + application/json: + schema: + $ref: "#/components/schemas/EnvironmentCollection" + post: + summary: Create an environment + description: Creates a new environment in a space + operationId: createEnvironment + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/EnvironmentCreate" + responses: + "201": + description: Created + content: + application/json: + schema: + $ref: "#/components/schemas/Environment" + + /spaces/{spaceId}/environments/{environmentId}: + parameters: + - $ref: "#/components/parameters/spaceId" + - $ref: "#/components/parameters/environmentId" + get: + summary: Get an environment + description: Retrieves a specific environment by ID + operationId: getEnvironment + responses: + "200": + description: Success + content: + application/json: + schema: + $ref: "#/components/schemas/Environment" + put: + summary: Update an environment + description: Updates an environment + operationId: updateEnvironment + parameters: + - $ref: "#/components/parameters/resourceVersion" + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/EnvironmentUpdate" + responses: + "200": + description: Success + content: + application/json: + schema: + $ref: "#/components/schemas/Environment" + delete: + summary: Delete an environment + description: Deletes an environment + operationId: deleteEnvironment + parameters: + - $ref: "#/components/parameters/resourceVersion" + responses: + "204": + description: No Content + + /spaces/{spaceId}/environments/{environmentId}/content_types: + parameters: + - $ref: "#/components/parameters/spaceId" + - $ref: "#/components/parameters/environmentId" + get: + summary: Get all content types + description: Retrieves all content types in an environment + operationId: getAllContentTypes + parameters: + - $ref: "#/components/parameters/limit" + - $ref: "#/components/parameters/skip" + responses: + "200": + description: Success + content: + application/json: + schema: + $ref: "#/components/schemas/ContentTypeCollection" + post: + summary: Create a content type + description: Creates a new content type + operationId: createContentType + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/ContentTypeCreate" + responses: + "201": + description: Created + content: + application/json: + schema: + $ref: "#/components/schemas/ContentType" + + /spaces/{spaceId}/environments/{environmentId}/entries: + parameters: + - $ref: "#/components/parameters/spaceId" + - $ref: "#/components/parameters/environmentId" + get: + summary: Get all entries + description: Retrieves all entries in an environment + operationId: getAllEntries + parameters: + - $ref: "#/components/parameters/limit" + - $ref: "#/components/parameters/skip" + - name: content_type + in: query + schema: + type: string + description: Filter by content type + responses: + "200": + description: Success + content: + application/json: + schema: + $ref: "#/components/schemas/EntryCollection" + post: + summary: Create an entry + description: Creates a new entry + operationId: createEntry + parameters: + - name: content_type + in: query + required: true + schema: + type: string + description: Content type ID for the new entry + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/EntryCreate" + responses: + "201": + description: Created + content: + application/json: + schema: + $ref: "#/components/schemas/Entry" + + /spaces/{spaceId}/environments/{environmentId}/entries/{entryId}: + parameters: + - $ref: "#/components/parameters/spaceId" + - $ref: "#/components/parameters/environmentId" + - $ref: "#/components/parameters/entryId" + + get: + summary: Get an entry + description: Retrieves a specific entry by ID + operationId: getEntry + responses: + "200": + description: Success + content: + application/json: + schema: + $ref: "#/components/schemas/Entry" + put: + summary: Update an entry + description: Updates an entry + operationId: updateEntry + parameters: + - $ref: "#/components/parameters/resourceVersion" + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/EntryUpdate" + responses: + "200": + description: Success + content: + application/json: + schema: + $ref: "#/components/schemas/Entry" + delete: + summary: Delete an entry + description: Deletes an entry + operationId: deleteEntry + parameters: + - $ref: "#/components/parameters/resourceVersion" + responses: + "204": + description: No Content + + /spaces/{spaceId}/environments/{environmentId}/entries/{entryId}/published: + parameters: + - $ref: "#/components/parameters/spaceId" + - $ref: "#/components/parameters/environmentId" + - $ref: "#/components/parameters/entryId" + put: + summary: Publish an entry + description: Publishes an entry + operationId: publishEntry + responses: + "200": + description: Success + content: + application/json: + schema: + $ref: "#/components/schemas/Entry" + delete: + summary: Unpublish an entry + description: Unpublishes an entry + operationId: unpublishEntry + responses: + "200": + description: Success + content: + application/json: + schema: + $ref: "#/components/schemas/Entry" + + /spaces/{spaceId}/environments/{environmentId}/entries/{entryId}/archived: + parameters: + - $ref: "#/components/parameters/spaceId" + - $ref: "#/components/parameters/environmentId" + - $ref: "#/components/parameters/entryId" + put: + summary: Archive an entry + description: Archives an entry + operationId: archiveEntry + responses: + "200": + description: Success + content: + application/json: + schema: + $ref: "#/components/schemas/Entry" + delete: + summary: Unarchive an entry + description: Unarchives an entry + operationId: unarchiveEntry + responses: + "200": + description: Success + content: + application/json: + schema: + $ref: "#/components/schemas/Entry" + + /spaces/{spaceId}/environments/{environmentId}/assets: + parameters: + - $ref: "#/components/parameters/spaceId" + - $ref: "#/components/parameters/environmentId" + get: + summary: Get all assets + description: Retrieves all assets in an environment + operationId: getAllAssets + parameters: + - $ref: "#/components/parameters/limit" + - $ref: "#/components/parameters/skip" + responses: + "200": + description: Success + content: + application/json: + schema: + $ref: "#/components/schemas/AssetCollection" + post: + summary: Create an asset + description: Creates a new asset + operationId: createAsset + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/AssetCreate" + responses: + "201": + description: Created + content: + application/json: + schema: + $ref: "#/components/schemas/Asset" + + /spaces/{spaceId}/webhook_definitions: + parameters: + - $ref: "#/components/parameters/spaceId" + get: + summary: Get all webhooks + description: Retrieves all webhooks in a space + operationId: getAllWebhooks + parameters: + - $ref: "#/components/parameters/limit" + - $ref: "#/components/parameters/skip" + responses: + "200": + description: Success + content: + application/json: + schema: + $ref: "#/components/schemas/WebhookCollection" + post: + summary: Create a webhook + description: Creates a new webhook in a space + operationId: createWebhook + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/WebhookCreate" + responses: + "201": + description: Created + content: + application/json: + schema: + $ref: "#/components/schemas/Webhook" + + /spaces/{spaceId}/webhook_definitions/{webhookId}: + parameters: + - $ref: "#/components/parameters/spaceId" + - $ref: "#/components/parameters/webhookId" + get: + summary: Get a webhook + description: Retrieves a specific webhook by ID + operationId: getWebhook + responses: + "200": + description: Success + content: + application/json: + schema: + $ref: "#/components/schemas/Webhook" + put: + summary: Update a webhook + description: Updates a webhook + operationId: updateWebhook + parameters: + - $ref: "#/components/parameters/resourceVersion" + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/WebhookUpdate" + responses: + "200": + description: Success + content: + application/json: + schema: + $ref: "#/components/schemas/Webhook" + delete: + summary: Delete a webhook + description: Deletes a webhook + operationId: deleteWebhook + parameters: + - $ref: "#/components/parameters/resourceVersion" + responses: + "204": + description: No Content + + /spaces/{spaceId}/environments/{environmentId}/locales: + parameters: + - $ref: "#/components/parameters/spaceId" + - $ref: "#/components/parameters/environmentId" + get: + summary: Get all locales + description: Retrieves all locales in an environment + operationId: getAllLocales + parameters: + - $ref: "#/components/parameters/limit" + - $ref: "#/components/parameters/skip" + responses: + "200": + description: Success + content: + application/json: + schema: + $ref: "#/components/schemas/LocaleCollection" + post: + summary: Create a locale + description: Creates a new locale in an environment + operationId: createLocale + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/LocaleCreate" + responses: + "201": + description: Created + content: + application/json: + schema: + $ref: "#/components/schemas/Locale" + + /spaces/{spaceId}/environments/{environmentId}/locales/{localeId}: + parameters: + - $ref: "#/components/parameters/spaceId" + - $ref: "#/components/parameters/environmentId" + - $ref: "#/components/parameters/localeId" + get: + summary: Get a locale + description: Retrieves a specific locale by ID + operationId: getLocale + responses: + "200": + description: Success + content: + application/json: + schema: + $ref: "#/components/schemas/Locale" + put: + summary: Update a locale + description: Updates a locale + operationId: updateLocale + parameters: + - $ref: "#/components/parameters/resourceVersion" + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/LocaleUpdate" + responses: + "200": + description: Success + content: + application/json: + schema: + $ref: "#/components/schemas/Locale" + delete: + summary: Delete a locale + description: Deletes a locale + operationId: deleteLocale + responses: + "204": + description: No Content + +components: + parameters: + spaceId: + name: spaceId + in: path + required: true + schema: + type: string + description: ID of the space + environmentId: + name: environmentId + in: path + required: true + schema: + type: string + description: ID of the environment + limit: + name: limit + in: query + required: false + schema: + type: integer + minimum: 1 + maximum: 1000 + default: 100 + description: Maximum number of items to return + skip: + name: skip + in: query + required: false + schema: + type: integer + minimum: 0 + default: 0 + description: Number of items to skip + localeId: + name: localeId + in: path + required: true + schema: + type: string + description: ID of the locale + webhookId: + name: webhookId + in: path + required: true + schema: + type: string + description: ID of the webhook + contentTypeHeader: + name: Content-Type + in: header + required: true + schema: + type: string + default: application/vnd.contentful.management.v1+json + description: Contentful Management API version header + entryId: + name: entryId + in: path + required: true + schema: + type: string + description: ID of the environment + resourceVersion: + name: X-Contentful-Version + in: header + required: true + description: The version of the locale to update. + schema: + type: integer + + securitySchemes: + bearerAuth: + type: http + scheme: bearer + bearerFormat: JWT + description: Use your Contentful personal access token + + schemas: + Asset: + type: object + properties: + fields: + properties: + description: + additionalProperties: + type: string + description: Asset description by locale + type: object + file: + additionalProperties: + properties: + contentType: + type: string + details: + properties: + image: + properties: + height: + type: integer + width: + type: integer + type: object + size: + type: integer + type: object + fileName: + type: string + url: + type: string + type: object + description: Asset file details by locale + type: object + title: + additionalProperties: + type: string + description: Asset title by locale + type: object + type: object + sys: + $ref: '#/components/schemas/SystemProperties' + + AssetCollection: + type: object + properties: + items: + items: + $ref: '#/components/schemas/Asset' + type: array + limit: + description: Maximum number of assets returned + type: integer + skip: + description: Number of assets skipped + type: integer + sys: + properties: + type: + enum: [Array] + type: string + type: object + total: + description: Total number of assets + type: integer + + AssetCreate: + type: object + properties: + fields: + properties: + description: + additionalProperties: + type: string + description: Asset description by locale + type: object + file: + additionalProperties: + properties: + contentType: + type: string + fileName: + type: string + upload: + description: Upload URL + type: string + type: object + description: Asset file details by locale + type: object + title: + additionalProperties: + type: string + description: Asset title by locale + type: object + type: object + + ContentType: + type: object + properties: + description: + description: Description of the content type + type: string + displayField: + description: ID of the field to use as the display field + type: string + fields: + items: + $ref: '#/components/schemas/Field' + type: array + name: + description: Name of the content type + type: string + sys: + $ref: '#/components/schemas/SystemProperties' + + ContentTypeCollection: + type: object + properties: + items: + items: + $ref: '#/components/schemas/ContentType' + type: array + limit: + description: Maximum number of content types returned + type: integer + skip: + description: Number of content types skipped + type: integer + sys: + properties: + type: + enum: [Array] + type: string + type: object + total: + description: Total number of content types + type: integer + + ContentTypeCreate: + type: object + properties: + description: + description: Description of the content type + type: string + displayField: + description: ID of the field to use as the display field + type: string + fields: + items: + $ref: '#/components/schemas/Field' + type: array + name: + description: Name of the content type + type: string + required: + - name + - fields + + Entry: + type: object + properties: + fields: + additionalProperties: true + description: Content fields with values by locale + type: object + sys: + $ref: '#/components/schemas/SystemProperties' + + EntryCollection: + type: object + properties: + items: + items: + $ref: '#/components/schemas/Entry' + type: array + limit: + description: Maximum number of entries returned + type: integer + skip: + description: Number of entries skipped + type: integer + sys: + properties: + type: + enum: [Array] + type: string + type: object + total: + description: Total number of entries + type: integer + + EntryCreate: + type: object + properties: + fields: + additionalProperties: true + description: Content fields with values by locale + type: object + + EntryUpdate: + type: object + properties: + fields: + additionalProperties: true + description: Content fields with values by locale + type: object + + Environment: + type: object + properties: + name: + description: Name of the environment + type: string + sys: + $ref: '#/components/schemas/SystemProperties' + + EnvironmentCollection: + type: object + properties: + items: + items: + $ref: '#/components/schemas/Environment' + type: array + limit: + description: Maximum number of environments returned + type: integer + skip: + description: Number of environments skipped + type: integer + sys: + properties: + type: + enum: [Array] + type: string + type: object + total: + description: Total number of environments + type: integer + + EnvironmentCreate: + type: object + properties: + name: + description: Name of the environment to create + type: string + required: + - name + + EnvironmentSystemProperties: + type: object + properties: + sys: + properties: + id: + description: Environment ID + type: string + linkType: + enum: [Environment] + type: string + type: + enum: [Link] + type: string + type: object + + EnvironmentUpdate: + type: object + properties: + name: + description: Updated name for the environment + type: string + required: + - name + + Field: + type: object + properties: + id: + description: ID of the field + type: string + items: + description: Used for Array fields to define the items type + type: object + linkType: + description: For Link fields, defines what type of resource it links to + enum: [Entry, Asset] + type: string + localized: + description: Whether the field is localized + type: boolean + name: + description: Name of the field + type: string + required: + description: Whether the field is required + type: boolean + type: + description: Type of the field + enum: + - Symbol + - Text + - Integer + - Number + - Date + - Location + - Boolean + - Link + - Array + - Object + type: string + required: + - id + - name + - type + + Locale: + type: object + properties: + code: + description: Locale code (e.g., en-US, de-DE) + type: string + contentDeliveryApi: + description: Whether this locale is available in the content delivery API + type: boolean + contentManagementApi: + description: Whether this locale is available in the content management API + type: boolean + default: + description: Whether this is the default locale + type: boolean + fallbackCode: + description: Code of the locale to use as a fallback + type: string + name: + description: Human readable name of the locale + type: string + optional: + description: Whether this locale is optional for content + type: boolean + sys: + $ref: '#/components/schemas/SystemProperties' + + LocaleCollection: + type: object + properties: + items: + items: + $ref: '#/components/schemas/Locale' + type: array + limit: + description: Maximum number of locales returned + type: integer + skip: + description: Number of locales skipped + type: integer + sys: + properties: + type: + enum: [Array] + type: string + type: object + total: + description: Total number of locales + type: integer + + LocaleCreate: + type: object + properties: + code: + description: Locale code (e.g., en-US, de-DE) + type: string + contentDeliveryApi: + default: true + description: Whether this locale is available in the content delivery API + type: boolean + contentManagementApi: + default: true + description: Whether this locale is available in the content management API + type: boolean + default: + default: false + description: Whether this is the default locale + type: boolean + fallbackCode: + description: Code of the locale to use as a fallback + nullable: true + type: string + name: + description: Human readable name of the locale + type: string + optional: + default: false + description: Whether this locale is optional for content + type: boolean + required: + - name + - code + + LocaleUpdate: + type: object + properties: + code: + description: Locale code (e.g., en-US, de-DE) + type: string + contentDeliveryApi: + description: Whether this locale is available in the content delivery API + type: boolean + contentManagementApi: + description: Whether this locale is available in the content management API + type: boolean + fallbackCode: + description: Code of the locale to use as a fallback + nullable: true + type: string + name: + description: Human readable name of the locale + type: string + optional: + description: Whether this locale is optional for content + type: boolean + required: + - name + - code + + Space: + type: object + properties: + defaultLocale: + description: Default locale of the space + type: string + name: + description: Name of the space + type: string + sys: + $ref: '#/components/schemas/SystemProperties' + + SpaceCollection: + type: object + properties: + items: + items: + $ref: '#/components/schemas/Space' + type: array + limit: + description: Maximum number of spaces returned + type: integer + skip: + description: Number of spaces skipped + type: integer + sys: + properties: + type: + enum: [Array] + type: string + type: object + total: + description: Total number of spaces + type: integer + + SpaceCreate: + type: object + properties: + defaultLocale: + default: en-US + description: Default locale for the space + type: string + name: + description: Name of the space to create + type: string + required: + - name + + SpaceUpdate: + type: object + properties: + name: + description: Updated name for the space + type: string + required: + - name + + SystemProperties: + type: object + properties: + archivedAt: + description: Archival timestamp + format: date-time + type: string + contentType: + properties: + sys: + properties: + id: + description: Content type ID + type: string + linkType: + enum: [ContentType] + type: string + type: + enum: [Link] + type: string + type: object + type: object + createdAt: + description: Creation timestamp + format: date-time + type: string + environment: + properties: + sys: + properties: + id: + description: Environment ID + type: string + linkType: + enum: [Environment] + type: string + type: + enum: [Link] + type: string + type: object + type: object + id: + description: Resource ID + type: string + publishedAt: + description: Publication timestamp + format: date-time + type: string + space: + $ref: '#/components/schemas/EnvironmentSystemProperties' + type: object + type: + description: Resource type + type: string + updatedAt: + description: Last update timestamp + format: date-time + type: string + version: + description: Resource version + type: integer + + Webhook: + type: object + properties: + headers: + description: HTTP headers to send with the webhook request + items: + $ref: '#/components/schemas/WebhookHeader' + type: object + type: array + httpBasicPassword: + description: Password for HTTP basic authentication + type: string + httpBasicUsername: + description: Username for HTTP basic authentication + type: string + name: + description: Name of the webhook + type: string + sys: + $ref: '#/components/schemas/SystemProperties' + topics: + description: Events that trigger the webhook + items: + type: string + type: array + url: + description: URL to call when the webhook is triggered + type: string + required: + - name + - url + - topics + - headers + + WebhookCollection: + type: object + properties: + items: + items: + $ref: '#/components/schemas/Webhook' + type: array + limit: + description: Maximum number of webhooks returned + type: integer + skip: + description: Number of webhooks skipped + type: integer + sys: + properties: + type: + enum: [Array] + type: string + type: object + total: + description: Total number of webhooks + type: integer + + WebhookCreate: + type: object + properties: + headers: + description: HTTP headers to send with the webhook request + items: + $ref: '#/components/schemas/WebhookHeader' + type: object + type: array + httpBasicPassword: + description: Password for HTTP basic authentication + type: string + httpBasicUsername: + description: Username for HTTP basic authentication + type: string + name: + description: Name of the webhook + type: string + topics: + description: Events that trigger the webhook + items: + type: string + type: array + url: + description: URL to call when the webhook is triggered + type: string + required: + - name + - url + - topics + + WebhookHeader: + type: object + properties: + key: + type: string + value: + type: string + required: + - key + - value + + WebhookUpdate: + type: object + properties: + headers: + description: HTTP headers to send with the webhook request + items: + $ref: '#/components/schemas/WebhookHeader' + type: object + type: array + httpBasicPassword: + description: Password for HTTP basic authentication + type: string + httpBasicUsername: + description: Username for HTTP basic authentication + type: string + name: + description: Name of the webhook + type: string + topics: + description: Events that trigger the webhook + items: + type: string + type: array + url: + description: URL to call when the webhook is triggered + type: string + required: + - name + - url + - topics diff --git a/tools.go b/tools.go index cc7a70a..9ba48a4 100644 --- a/tools.go +++ b/tools.go @@ -7,4 +7,5 @@ import ( // document generation _ "github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs" + _ "github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen" )