From 4c100fb98c052684e4089b9520014e3b401298a8 Mon Sep 17 00:00:00 2001 From: Erran Carey Date: Sun, 17 Sep 2017 09:34:30 +0100 Subject: [PATCH 1/4] Add support for terraform import by id for all kong resources --- kong/resource_kong_api.go | 4 ++++ kong/resource_kong_api_plugin.go | 4 ++++ kong/resource_kong_consumer.go | 4 ++++ kong/resource_kong_consumer_credential_basic_auth.go | 4 ++++ kong/resource_kong_consumer_credential_jwt.go | 4 ++++ kong/resource_kong_consumer_credential_key_auth.go | 4 ++++ kong/resource_kong_key_auth_plugin.go | 4 ++++ 7 files changed, 28 insertions(+) diff --git a/kong/resource_kong_api.go b/kong/resource_kong_api.go index 66a8c2a7..bf56992e 100644 --- a/kong/resource_kong_api.go +++ b/kong/resource_kong_api.go @@ -52,6 +52,10 @@ func resourceKongAPI() *schema.Resource { Update: resourceKongAPIUpdate, Delete: resourceKongAPIDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + Schema: map[string]*schema.Schema{ "id": &schema.Schema{ Type: schema.TypeString, diff --git a/kong/resource_kong_api_plugin.go b/kong/resource_kong_api_plugin.go index 8caef282..67073f20 100644 --- a/kong/resource_kong_api_plugin.go +++ b/kong/resource_kong_api_plugin.go @@ -23,6 +23,10 @@ func resourceKongPlugin() *schema.Resource { Update: resourceKongPluginUpdate, Delete: resourceKongPluginDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + Schema: map[string]*schema.Schema{ "id": &schema.Schema{ Type: schema.TypeString, diff --git a/kong/resource_kong_consumer.go b/kong/resource_kong_consumer.go index 0b00ea6d..43420375 100644 --- a/kong/resource_kong_consumer.go +++ b/kong/resource_kong_consumer.go @@ -21,6 +21,10 @@ func resourceKongConsumer() *schema.Resource { Update: resourceKongConsumerUpdate, Delete: resourceKongConsumerDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + Schema: map[string]*schema.Schema{ "id": &schema.Schema{ Type: schema.TypeString, diff --git a/kong/resource_kong_consumer_credential_basic_auth.go b/kong/resource_kong_consumer_credential_basic_auth.go index aebffd0a..58718a5f 100644 --- a/kong/resource_kong_consumer_credential_basic_auth.go +++ b/kong/resource_kong_consumer_credential_basic_auth.go @@ -22,6 +22,10 @@ func resourceKongBasicAuthCredential() *schema.Resource { Update: resourceKongBasicAuthCredentialUpdate, Delete: resourceKongBasicAuthCredentialDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + Schema: map[string]*schema.Schema{ "id": &schema.Schema{ Type: schema.TypeString, diff --git a/kong/resource_kong_consumer_credential_jwt.go b/kong/resource_kong_consumer_credential_jwt.go index 7921d910..4d8504fe 100644 --- a/kong/resource_kong_consumer_credential_jwt.go +++ b/kong/resource_kong_consumer_credential_jwt.go @@ -24,6 +24,10 @@ func resourceKongJWTCredential() *schema.Resource { Update: resourceKongJWTCredentialUpdate, Delete: resourceKongJWTCredentialDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + Schema: map[string]*schema.Schema{ "id": &schema.Schema{ Type: schema.TypeString, diff --git a/kong/resource_kong_consumer_credential_key_auth.go b/kong/resource_kong_consumer_credential_key_auth.go index 0aa2c86e..fa5471df 100644 --- a/kong/resource_kong_consumer_credential_key_auth.go +++ b/kong/resource_kong_consumer_credential_key_auth.go @@ -21,6 +21,10 @@ func resourceKongKeyAuthCredential() *schema.Resource { Update: resourceKongKeyAuthCredentialUpdate, Delete: resourceKongKeyAuthCredentialDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + Schema: map[string]*schema.Schema{ "id": &schema.Schema{ Type: schema.TypeString, diff --git a/kong/resource_kong_key_auth_plugin.go b/kong/resource_kong_key_auth_plugin.go index 842da246..f4125291 100644 --- a/kong/resource_kong_key_auth_plugin.go +++ b/kong/resource_kong_key_auth_plugin.go @@ -24,6 +24,10 @@ func resourceKongKeyAuthPlugin() *schema.Resource { Update: resourceKeyAuthPluginUpdate, Delete: resourceKeyAuthPluginDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + Schema: map[string]*schema.Schema{ "id": &schema.Schema{ Type: schema.TypeString, From 66043769a2f69fceb7d5e6e93441875af28a9dc0 Mon Sep 17 00:00:00 2001 From: Erran Carey Date: Sun, 17 Sep 2017 09:58:35 +0100 Subject: [PATCH 2/4] Return a more specific error for 409 Conflict In the case that a user hits a conflict when creating a new resource they should use terraform import to start managing the resource through the terraform kong provider. --- kong/resource_kong_api.go | 4 +++- kong/resource_kong_api_plugin.go | 4 +++- kong/resource_kong_consumer.go | 4 +++- kong/resource_kong_key_auth_plugin.go | 4 +++- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/kong/resource_kong_api.go b/kong/resource_kong_api.go index bf56992e..9a14403b 100644 --- a/kong/resource_kong_api.go +++ b/kong/resource_kong_api.go @@ -166,7 +166,9 @@ func resourceKongAPICreate(d *schema.ResourceData, meta interface{}) error { return fmt.Errorf("error while creating API: " + error.Error()) } - if response.StatusCode != http.StatusCreated { + if response.StatusCode == http.StatusConflict { + return fmt.Errorf("409 Conflict - use terraform import to manage this api.") + } else if response.StatusCode != http.StatusCreated { return fmt.Errorf("unexpected status code received: " + response.Status) } diff --git a/kong/resource_kong_api_plugin.go b/kong/resource_kong_api_plugin.go index 67073f20..6d420966 100644 --- a/kong/resource_kong_api_plugin.go +++ b/kong/resource_kong_api_plugin.go @@ -67,7 +67,9 @@ func resourceKongPluginCreate(d *schema.ResourceData, meta interface{}) error { return fmt.Errorf("error while creating plugin: " + error.Error()) } - if response.StatusCode != http.StatusCreated { + if response.StatusCode == http.StatusConflict { + return fmt.Errorf("409 Conflict - use terraform import to manage this plugin.") + } else if response.StatusCode != http.StatusCreated { return fmt.Errorf("unexpected status code received: " + response.Status) } diff --git a/kong/resource_kong_consumer.go b/kong/resource_kong_consumer.go index 43420375..1e19e010 100644 --- a/kong/resource_kong_consumer.go +++ b/kong/resource_kong_consumer.go @@ -60,7 +60,9 @@ func resourceKongConsumerCreate(d *schema.ResourceData, meta interface{}) error return fmt.Errorf("Error while creating consumer.") } - if response.StatusCode != http.StatusCreated { + if response.StatusCode == http.StatusConflict { + return fmt.Errorf("409 Conflict - use terraform import to manage this consumer.") + } else if response.StatusCode != http.StatusCreated { return fmt.Errorf(response.Status) } diff --git a/kong/resource_kong_key_auth_plugin.go b/kong/resource_kong_key_auth_plugin.go index f4125291..03f22883 100644 --- a/kong/resource_kong_key_auth_plugin.go +++ b/kong/resource_kong_key_auth_plugin.go @@ -75,7 +75,9 @@ func resourceKeyAuthPluginCreate(d *schema.ResourceData, meta interface{}) error return fmt.Errorf("Error while creating plugin.") } - if response.StatusCode != http.StatusCreated { + if response.StatusCode == http.StatusConflict { + return fmt.Errorf("409 Conflict - use terraform import to manage this plugin.") + } else if response.StatusCode != http.StatusCreated { return fmt.Errorf(response.Status) } From 5dfb8cb8b1129c345840406491cf719e3d90b98a Mon Sep 17 00:00:00 2001 From: Erran Carey Date: Sun, 17 Sep 2017 10:32:48 +0100 Subject: [PATCH 3/4] Copy api id on terraform import of plugins The plugin response object includes an api_id field. Adding it to the Plugin type means we can import and have api set correctly in state. --- kong/resource_kong_api_plugin.go | 2 +- kong/resource_kong_key_auth_plugin.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/kong/resource_kong_api_plugin.go b/kong/resource_kong_api_plugin.go index 6d420966..d174e855 100644 --- a/kong/resource_kong_api_plugin.go +++ b/kong/resource_kong_api_plugin.go @@ -13,7 +13,7 @@ type Plugin struct { ID string `json:"id,omitempty"` Name string `json:"name,omitempty"` Configuration map[string]interface{} `json:"config,omitempty"` - API string `json:"-"` + API string `json:"api_id,omitempty"` } func resourceKongPlugin() *schema.Resource { diff --git a/kong/resource_kong_key_auth_plugin.go b/kong/resource_kong_key_auth_plugin.go index 03f22883..8897b854 100644 --- a/kong/resource_kong_key_auth_plugin.go +++ b/kong/resource_kong_key_auth_plugin.go @@ -14,7 +14,7 @@ type KeyAuthPlugin struct { KeyNames string `json:"config.key_names,omitempty"` HideCredentials bool `json:"config.hide_credentials,omitempty"` Anonymous string `json:"config.anonymous,omitempty"` - API string `json:"-"` + API string `json:"api_id,omitempty"` } func resourceKongKeyAuthPlugin() *schema.Resource { From 94f4aaed6a70c5aad448450702fb36e4a746eb9b Mon Sep 17 00:00:00 2001 From: Erran Carey Date: Sun, 17 Sep 2017 22:54:57 +0100 Subject: [PATCH 4/4] Use / format for credential import This prevents terraform from failing to call read the credential resource (due to not having a consumer in the temporary state). --- kong/import_consumer_credential.go | 19 +++++++++++++++++++ ...rce_kong_consumer_credential_basic_auth.go | 2 +- kong/resource_kong_consumer_credential_jwt.go | 2 +- ...ource_kong_consumer_credential_key_auth.go | 2 +- 4 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 kong/import_consumer_credential.go diff --git a/kong/import_consumer_credential.go b/kong/import_consumer_credential.go new file mode 100644 index 00000000..be4daa75 --- /dev/null +++ b/kong/import_consumer_credential.go @@ -0,0 +1,19 @@ +package kong + +import ( + "fmt" + "strings" + + "github.com/hashicorp/terraform/helper/schema" +) + +func ImportConsumerCredential(d *schema.ResourceData, m interface{}) ([]*schema.ResourceData, error) { + parts := strings.Split(d.Id(), "/") + if len(parts) != 2 { + return nil, fmt.Errorf("Expected a string in the format \"/\" to import.") + } + + d.Set("consumer", parts[0]) + d.SetId(parts[1]) + return []*schema.ResourceData{d}, nil +} diff --git a/kong/resource_kong_consumer_credential_basic_auth.go b/kong/resource_kong_consumer_credential_basic_auth.go index 58718a5f..97f17f08 100644 --- a/kong/resource_kong_consumer_credential_basic_auth.go +++ b/kong/resource_kong_consumer_credential_basic_auth.go @@ -23,7 +23,7 @@ func resourceKongBasicAuthCredential() *schema.Resource { Delete: resourceKongBasicAuthCredentialDelete, Importer: &schema.ResourceImporter{ - State: schema.ImportStatePassthrough, + State: ImportConsumerCredential, }, Schema: map[string]*schema.Schema{ diff --git a/kong/resource_kong_consumer_credential_jwt.go b/kong/resource_kong_consumer_credential_jwt.go index 4d8504fe..ae6b9010 100644 --- a/kong/resource_kong_consumer_credential_jwt.go +++ b/kong/resource_kong_consumer_credential_jwt.go @@ -25,7 +25,7 @@ func resourceKongJWTCredential() *schema.Resource { Delete: resourceKongJWTCredentialDelete, Importer: &schema.ResourceImporter{ - State: schema.ImportStatePassthrough, + State: ImportConsumerCredential, }, Schema: map[string]*schema.Schema{ diff --git a/kong/resource_kong_consumer_credential_key_auth.go b/kong/resource_kong_consumer_credential_key_auth.go index fa5471df..09a11a09 100644 --- a/kong/resource_kong_consumer_credential_key_auth.go +++ b/kong/resource_kong_consumer_credential_key_auth.go @@ -22,7 +22,7 @@ func resourceKongKeyAuthCredential() *schema.Resource { Delete: resourceKongKeyAuthCredentialDelete, Importer: &schema.ResourceImporter{ - State: schema.ImportStatePassthrough, + State: ImportConsumerCredential, }, Schema: map[string]*schema.Schema{