diff --git a/README.md b/README.md index 8eb5bc90..c870b7aa 100644 --- a/README.md +++ b/README.md @@ -11,15 +11,7 @@ Requirements - [Go](https://golang.org/doc/install) 1.8 (to build the provider plugin) Usage ---------------------- - -``` -# For example, restrict template version in 0.1.x -provider "template" { - version = "~> 0.1" -} -``` - +----- To configure the provider: ```hcl @@ -31,7 +23,9 @@ provider "kong" { By convention the provider will first check the env variable `KONG_ADMIN_ADDR` if that variable is not set then it will default to `http://localhost:8001` if you do not provide a provider block as above. -To create an api: +## Resources + +# Api ```hcl resource "kong_api" "api" { name = "TestApi" @@ -49,9 +43,9 @@ resource "kong_api" "api" { http_if_terminated = false } ``` -The api resource maps directly onto the json for creating an API in Kong. For more information on the parameters [see the Kong Api create documentation](https://getkong.org/docs/0.11.x/admin-api/#add-api). +The api resource maps directly onto the json for creating an API in Kong. For more information on the parameters [see the Kong Api create documentation](https://getkong.org/docs/0.11.x/admin-api/#api-object). -To create a consuemr: +# Consumer ```hcl resource "kong_consumer" "consumer" { username = "User1" @@ -59,4 +53,17 @@ resource "kong_consumer" "consumer" { } ``` -The consumer resource maps directly onto the json for creating an Consumer in Kong. For more information on the parameters [see the Kong Consumer create documentation](https://getkong.org/docs/0.11.x/admin-api/#create-consumer). \ No newline at end of file +The consumer resource maps directly onto the json for creating an Consumer in Kong. For more information on the parameters [see the Kong Consumer create documentation](https://getkong.org/docs/0.11.x/admin-api/#consumer-object). + +## Certificates +```hcl +resource "kong_certificate" "certificate" { + certificate = "public key --- 123 ----" + private_key = "private key --- 456 ----" +} +``` + +`certificate` should be the public key of your certificate it is mapped to the `Cert` parameter on the Kong API. +`private_key` should be the private key of your certificate it is mapped to the `Key` parameter on the Kong API. + +For more information on creating certificates in Kong [see their documentation](https://getkong.org/docs/0.11.x/admin-api/#certificate-object) \ No newline at end of file diff --git a/kong/provider.go b/kong/provider.go index 97e750f1..ce694f5c 100644 --- a/kong/provider.go +++ b/kong/provider.go @@ -19,8 +19,9 @@ func Provider() terraform.ResourceProvider { }, ResourcesMap: map[string]*schema.Resource{ - "kong_api": resourceKongApi(), - "kong_consumer": resourceKongConsumer(), + "kong_api": resourceKongApi(), + "kong_certificate": resourceKongCertificate(), + "kong_consumer": resourceKongConsumer(), }, ConfigureFunc: providerConfigure, diff --git a/kong/resource_kong_api_test.go b/kong/resource_kong_api_test.go index 1c8c8e43..7b071ed1 100644 --- a/kong/resource_kong_api_test.go +++ b/kong/resource_kong_api_test.go @@ -8,7 +8,7 @@ import ( "testing" ) -func TestAccKongApi_basic(t *testing.T) { +func TestAccKongApi(t *testing.T) { resource.Test(t, resource.TestCase{ Providers: testAccProviders, diff --git a/kong/resource_kong_certificate.go b/kong/resource_kong_certificate.go new file mode 100644 index 00000000..555f2f3d --- /dev/null +++ b/kong/resource_kong_certificate.go @@ -0,0 +1,105 @@ +package kong + +import ( + "fmt" + "github.com/hashicorp/terraform/helper/schema" + "github.com/kevholditch/gokong" +) + +func resourceKongCertificate() *schema.Resource { + return &schema.Resource{ + Create: resourceKongCertificateCreate, + Read: resourceKongCertificateRead, + Delete: resourceKongCertificateDelete, + Update: resourceKongCertificateUpdate, + + Schema: map[string]*schema.Schema{ + "certificate": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: false, + }, + "private_key": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + ForceNew: false, + }, + }, + } +} + +func resourceKongCertificateCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*gokong.KongAdminClient) + + certificateRequest := createKongCertificateRequestFromResourceData(d) + + consumer, err := client.Certificates().Create(certificateRequest) + + if err != nil { + return fmt.Errorf("failed to create kong certificate: %v error: %v", certificateRequest, err) + } + + d.SetId(consumer.Id) + + return resourceKongCertificateRead(d, meta) +} + +func resourceKongCertificateUpdate(d *schema.ResourceData, meta interface{}) error { + d.Partial(false) + + client := meta.(*gokong.KongAdminClient) + + certificateRequest := createKongCertificateRequestFromResourceData(d) + + id := d.Id() + + _, err := client.Certificates().UpdateById(id, certificateRequest) + + if err != nil { + return fmt.Errorf("error updating kong certificate: %s", err) + } + + return resourceKongCertificateRead(d, meta) +} + +func resourceKongCertificateRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*gokong.KongAdminClient) + + id := d.Id() + + certificate, err := client.Certificates().GetById(id) + + if err != nil { + return fmt.Errorf("could not find kong certificate: %v", err) + } + + d.Set("certificate", certificate.Cert) + d.Set("private_key", certificate.Key) + + return nil +} + +func resourceKongCertificateDelete(d *schema.ResourceData, meta interface{}) error { + + client := meta.(*gokong.KongAdminClient) + + id := d.Id() + + err := client.Consumers().DeleteById(id) + + if err != nil { + return fmt.Errorf("could not delete kong certificate: %v", err) + } + + return nil +} + +func createKongCertificateRequestFromResourceData(d *schema.ResourceData) *gokong.CertificateRequest { + + certificateRequest := &gokong.CertificateRequest{} + + certificateRequest.Cert = readStringFromResource(d, "certificate") + certificateRequest.Key = readStringFromResource(d, "private_key") + + return certificateRequest +} diff --git a/kong/resource_kong_certificate_test.go b/kong/resource_kong_certificate_test.go new file mode 100644 index 00000000..c7f2733c --- /dev/null +++ b/kong/resource_kong_certificate_test.go @@ -0,0 +1,98 @@ +package kong + +import ( + "fmt" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/kevholditch/gokong" + "testing" +) + +func TestAccKongCertificate(t *testing.T) { + + resource.Test(t, resource.TestCase{ + Providers: testAccProviders, + CheckDestroy: testAccCheckKongCertificateDestroy, + Steps: []resource.TestStep{ + { + Config: testCreateCertificateConfig, + Check: resource.ComposeTestCheckFunc( + testAccCheckKongCertificateExists("kong_certificate.certificate"), + resource.TestCheckResourceAttr("kong_certificate.certificate", "certificate", "public key --- 123 ----"), + resource.TestCheckResourceAttr("kong_certificate.certificate", "private_key", "private key --- 456 ----"), + ), + }, + { + Config: testUpdateCertificateConfig, + Check: resource.ComposeTestCheckFunc( + testAccCheckKongCertificateExists("kong_certificate.certificate"), + resource.TestCheckResourceAttr("kong_certificate.certificate", "certificate", "public key --- 789 ----"), + resource.TestCheckResourceAttr("kong_certificate.certificate", "private_key", "private key --- 321 ----"), + ), + }, + }, + }) +} + +func testAccCheckKongCertificateDestroy(state *terraform.State) error { + + client := testAccProvider.Meta().(*gokong.KongAdminClient) + + for _, rs := range state.RootModule().Resources { + if rs.Type != "kong_api" { + continue + } + + response, err := client.Certificates().GetById(rs.Primary.ID) + + if err != nil { + return fmt.Errorf("error calling get certificate by id: %v", err) + } + + if response != nil { + return fmt.Errorf("certificate %s still exists, %+v", rs.Primary.ID, response) + } + } + + return nil +} + +func testAccCheckKongCertificateExists(resourceKey string) resource.TestCheckFunc { + + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[resourceKey] + + if !ok { + return fmt.Errorf("not found: %s", resourceKey) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("no ID is set") + } + + api, err := testAccProvider.Meta().(*gokong.KongAdminClient).Certificates().GetById(rs.Primary.ID) + + if err != nil { + return err + } + + if api == nil { + return fmt.Errorf("certificate with id %v not found", rs.Primary.ID) + } + + return nil + } +} + +const testCreateCertificateConfig = ` +resource "kong_certificate" "certificate" { + certificate = "public key --- 123 ----" + private_key = "private key --- 456 ----" +} +` +const testUpdateCertificateConfig = ` +resource "kong_certificate" "certificate" { + certificate = "public key --- 789 ----" + private_key = "private key --- 321 ----" +} +` diff --git a/kong/resource_kong_consumer_test.go b/kong/resource_kong_consumer_test.go index 56b49e3e..4e0983ad 100644 --- a/kong/resource_kong_consumer_test.go +++ b/kong/resource_kong_consumer_test.go @@ -8,7 +8,7 @@ import ( "testing" ) -func TestAccKongConsumer_basic(t *testing.T) { +func TestAccKongConsumer(t *testing.T) { resource.Test(t, resource.TestCase{ Providers: testAccProviders, diff --git a/kong/resource_reader.go b/kong/resource_reader.go index 052945d9..7900b7a6 100644 --- a/kong/resource_reader.go +++ b/kong/resource_reader.go @@ -5,7 +5,7 @@ import "github.com/hashicorp/terraform/helper/schema" func readArrayFromResource(d *schema.ResourceData, key string) []string { if attr, ok := d.GetOk(key); ok { - array := []string{} + var array []string items := attr.([]interface{}) for _, x := range items { item := x.(string) diff --git a/vendor/github.com/kevholditch/gokong/LICENSE.md b/vendor/github.com/kevholditch/gokong/LICENSE.md new file mode 100644 index 00000000..bae62a49 --- /dev/null +++ b/vendor/github.com/kevholditch/gokong/LICENSE.md @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) [2017] [Kevin Holditch] + +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. diff --git a/vendor/github.com/kevholditch/gokong/README.md b/vendor/github.com/kevholditch/gokong/README.md index f98c2c73..84c421a9 100644 --- a/vendor/github.com/kevholditch/gokong/README.md +++ b/vendor/github.com/kevholditch/gokong/README.md @@ -7,10 +7,6 @@ A kong go client fully tested with no mocks!! ## GoKong GoKong is a easy to use api client for [kong](https://getkong.org/). The difference with the gokong library is all of its tests are written against a real running kong running inside a docker container, yep that's right you won't see a horrible mock anywhere!! -## Run build -Ensure docker is installed then run: -`make` - ## Importing To add gokong via `go get`: @@ -213,6 +209,300 @@ consumerRequest := &gokong.ConsumerRequest{ updatedConsumer, err := gokong.NewClient(gokong.NewDefaultConfig()).Consumers().UpdateByUsername("User2", consumerRequest) ``` +## Plugins +Create a new Plugin to be applied to all APIs and consumers do not set `ApiId` or `ConsumerId`. Not all plugins can be configured in this way + ([for more information on the Plugin Fields see the Kong documentation](https://getkong.org/docs/0.11.x/admin-api/#add-plugin)): + +```go +pluginRequest := &gokong.PluginRequest{ + Name: "response-ratelimiting", + Config: map[string]interface{}{ + "limits.sms.minute": 20, + }, +} + +createdPlugin, err := gokong.NewClient(gokong.NewDefaultConfig()).Plugins().Create(pluginRequest) +``` + +Create a new Plugin for a single API (only set `ApiId`), not all plugins can be configured in this way ([for more information on the Plugin Fields see the Kong documentation](https://getkong.org/docs/0.11.x/admin-api/#add-plugin)): +```go +client := gokong.NewClient(gokong.NewDefaultConfig()) + +apiRequest := &gokong.ApiRequest{ + Name: "test-api", + Hosts: []string{"example.com"}, + Uris: []string{"/example"}, + Methods: []string{"GET", "POST"}, + UpstreamUrl: "http://localhost:4140/testservice", + StripUri: true, + PreserveHost: true, + Retries: 3, + UpstreamConnectTimeout: 1000, + UpstreamSendTimeout: 2000, + UpstreamReadTimeout: 3000, + HttpsOnly: true, + HttpIfTerminated: true, +} + +createdApi, err := client.Apis().Create(apiRequest) + +pluginRequest := &gokong.PluginRequest{ + Name: "response-ratelimiting", + ApiId: createdApi.Id, + Config: map[string]interface{}{ + "limits.sms.minute": 20, + }, +} + +createdPlugin, err := client.Plugins().Create(pluginRequest) +``` + +Create a new Plugin for a single Consumer (only set `ConsumerId`), Not all plugins can be configured in this way ([for more information on the Plugin Fields see the Kong documentation](https://getkong.org/docs/0.11.x/admin-api/#add-plugin)): +```go +client := gokong.NewClient(gokong.NewDefaultConfig()) + +consumerRequest := &gokong.ConsumerRequest{ + Username: "User1", + CustomId: "test", +} + +createdConsumer, err := client.Consumers().Create(consumerRequest) + +pluginRequest := &gokong.PluginRequest{ + Name: "response-ratelimiting", + ConsumerId: createdConsumer.Id, + Config: map[string]interface{}{ + "limits.sms.minute": 20, + }, +} + +createdPlugin, err := client.Plugins().Create(pluginRequest) +``` + +Create a new Plugin for a single Consumer and Api (set `ConsumerId` and `ApiId`), Not all plugins can be configured in this way ([for more information on the Plugin Fields see the Kong documentation](https://getkong.org/docs/0.11.x/admin-api/#add-plugin)): +```go +client := gokong.NewClient(gokong.NewDefaultConfig()) + +consumerRequest := &gokong.ConsumerRequest{ + Username: "User1", + CustomId: "test", +} + +createdConsumer, err := client.Consumers().Create(consumerRequest) + +apiRequest := &gokong.ApiRequest{ + Name: "test-api", + Hosts: []string{"example.com"}, + Uris: []string{"/example"}, + Methods: []string{"GET", "POST"}, + UpstreamUrl: "http://localhost:4140/testservice", + StripUri: true, + PreserveHost: true, + Retries: 3, + UpstreamConnectTimeout: 1000, + UpstreamSendTimeout: 2000, + UpstreamReadTimeout: 3000, + HttpsOnly: true, + HttpIfTerminated: true, +} + +createdApi, err := client.Apis().Create(apiRequest) + +pluginRequest := &gokong.PluginRequest{ + Name: "response-ratelimiting", + ConsumerId: createdConsumer.Id, + ApiId: createdApi.Id, + Config: map[string]interface{}{ + "limits.sms.minute": 20, + }, +} + +createdPlugin, err := client.Plugins().Create(pluginRequest) +``` + +Get a plugin by id: +```go +plugin, err := gokong.NewClient(gokong.NewDefaultConfig()).Plugins().GetById("04bda233-d035-4b8a-8cf2-a53f3dd990f3") +``` + +List all plugins: +```go +plugins, err := gokong.NewClient(gokong.NewDefaultConfig()).Plugins().List() +``` + +List all plugins with a filter: +```go +plugins, err := gokong.NewClient(gokong.NewDefaultConfig()).Plugins().ListFiltered(&gokong.PluginFilter{Name: "response-ratelimiting", ConsumerId: "7009a608-b40c-4a21-9a90-9219d5fd1ac7"}) +``` + +Delete a plugin by id: +```go +err := gokong.NewClient(gokong.NewDefaultConfig()).Plugins().DeleteById("f2bbbab8-3e6f-4d9d-bada-d486600b3b4c") +``` + +Update a plugin by id: +```go +updatePluginRequest := &gokong.PluginRequest{ + Name: "response-ratelimiting", + ConsumerId: createdConsumer.Id, + ApiId: createdApi.Id, + Config: map[string]interface{}{ + "limits.sms.minute": 20, + }, +} + +updatedPlugin, err := gokong.NewClient(gokong.NewDefaultConfig()).Plugins().UpdateById("70692eed-2293-486d-b992-db44a6459360", updatePluginRequest) +``` + +## Certificates +Create a Certificate ([for more information on the Certificate Fields see the Kong documentation](https://getkong.org/docs/0.11.x/admin-api/#add-certificate)): + +```go +certificateRequest := &gokong.CertificateRequest{ + Cert: "public key --- 123", + Key: "private key --- 456", +} + +createdCertificate, err := gokong.NewClient(gokong.NewDefaultConfig()).Certificates().Create(certificateRequest) +``` + +Get a Certificate by id: +```go +certificate, err := gokong.NewClient(gokong.NewDefaultConfig()).Certificates().GetById("0408cbd4-e856-4565-bc11-066326de9231") +``` + +List all certificates: +```go +certificates, err := gokong.NewClient(gokong.NewDefaultConfig()).Certificates().List() +``` + +Delete a Certificate: +```go +err := gokong.NewClient(gokong.NewDefaultConfig()).Certificates().DeleteById("db884cf2-9dd7-4e33-9ef5-628165076a42") +``` + +Update a Certificate: +```go +updateCertificateRequest := &gokong.CertificateRequest{ + Cert: "public key --- 789", + Key: "private key --- 111", +} + +updatedCertificate, err := gokong.NewClient(gokong.NewDefaultConfig()).Certificates().UpdateById("1dc11281-30a6-4fb9-aec2-c6ff33445375", updateCertificateRequest) +``` + + +## SNIs +Create an SNI ([for more information on the Sni Fields see the Kong documentation](https://getkong.org/docs/0.11.x/admin-api/#add-sni)): +```go +client := gokong.NewClient(gokong.NewDefaultConfig()) + +certificateRequest := &gokong.CertificateRequest{ + Cert: "public key --- 123", + Key: "private key --- 111", +} + +certificate, err := client.Certificates().Create(certificateRequest) + +snisRequest := &gokong.SnisRequest{ + Name: "example.com", + SslCertificateId: certificate.Id, +} + +sni, err := client.Snis().Create(snisRequest) +``` + +Get an SNI by name: +```go +sni, err := client.Snis().GetByName("example.com") +``` + +List all SNIs: +``` +snis, err := client.Snis().List() +``` + +Delete an SNI by name: +```go +err := client.Snis().DeleteByName("example.com") +``` + +Update an SNI by name: +```go +updateSniRequest := &gokong.SnisRequest{ + Name: "example.com", + SslCertificateId: "a9797703-3ae6-44a9-9f0a-4ebb5d7f301f", +} + +updatedSni, err := client.Snis().UpdateByName("example.com", updateSniRequest) +``` + +## Upstreams +Create an Upstream ([for more information on the Upstream Fields see the Kong documentation](https://getkong.org/docs/0.11.x/admin-api/#add-upstream)): +```go +upstreamRequest := &gokong.UpstreamRequest{ + Name: "test-upstream", + Slots: 10, +} + +createdUpstream, err := gokong.NewClient(gokong.NewDefaultConfig()).Upstreams().Create(upstreamRequest) +``` + +Get an Upstream by id: +```go +upstream, err := gokong.NewClient(gokong.NewDefaultConfig()).Upstreams().GetById("3705d962-caa8-4d0b-b291-4f0e85fe227a") +``` + +Get an Upstream by name: +```go +upstream, err := gokong.NewClient(gokong.NewDefaultConfig()).Upstreams().GetByName("test-upstream") +``` + +List all Upstreams: +```go +upstreams, err := gokong.NewClient(gokong.NewDefaultConfig()).Upstreams().List() +``` + +List all Upstreams with a filter: +```go +upstreams, err := gokong.NewClient(gokong.NewDefaultConfig()).Upstreams().ListFiltered(&gokong.UpstreamFilter{Name:"test-upstream", Slots:10}) +``` + +Delete an Upstream by id: +```go +err := gokong.NewClient(gokong.NewDefaultConfig()).Upstreams().DeleteById("3a46b122-47ee-4c5d-b2de-49be84a672e6") +``` + +Delete an Upstream by name: +```go +err := gokong.NewClient(gokong.NewDefaultConfig()).Upstreams().DeleteById("3a46b122-47ee-4c5d-b2de-49be84a672e6") +``` + +Delete an Upstream by id: +```go +err := gokong.NewClient(gokong.NewDefaultConfig()).Upstreams().DeleteByName("test-upstream") +``` + +Update an Upstream by id: +``` +updateUpstreamRequest := &gokong.UpstreamRequest{ + Name: "test-upstream", + Slots: 10, +} + +updatedUpstream, err := gokong.NewClient(gokong.NewDefaultConfig()).Upstreams().UpdateById("3a46b122-47ee-4c5d-b2de-49be84a672e6", updateUpstreamRequest) +``` + +Update an Upstream by name: +```go +updateUpstreamRequest := &gokong.UpstreamRequest{ + Name: "test-upstream", + Slots: 10, +} + +updatedUpstream, err := gokong.NewClient(gokong.NewDefaultConfig()).Upstreams().UpdateByName("test-upstream", updateUpstreamRequest) +``` + # Contributing I would love to get contributions to the project so please feel free to submit a PR. To setup your dev station you need go and docker installed. diff --git a/vendor/github.com/kevholditch/gokong/apis.go b/vendor/github.com/kevholditch/gokong/apis.go index cad6f0d7..90c35e84 100644 --- a/vendor/github.com/kevholditch/gokong/apis.go +++ b/vendor/github.com/kevholditch/gokong/apis.go @@ -123,7 +123,11 @@ func (apiClient *ApiClient) Create(newApi *ApiRequest) (*Api, error) { createdApi := &Api{} err := json.Unmarshal([]byte(body), createdApi) if err != nil { - return nil, fmt.Errorf("could not parse api creation response, error: %v", err) + return nil, fmt.Errorf("could not parse api creation response, error: %v %s", err, body) + } + + if createdApi.Id == "" { + return nil, fmt.Errorf("could not create api, error: %v", body) } return createdApi, nil @@ -160,5 +164,9 @@ func (apiClient *ApiClient) UpdateById(id string, apiRequest *ApiRequest) (*Api, return nil, fmt.Errorf("could not parse api update response, error: %v", err) } + if updatedApi.Id == "" { + return nil, fmt.Errorf("could not update certificate, error: %v", body) + } + return updatedApi, nil } diff --git a/vendor/github.com/kevholditch/gokong/certificates.go b/vendor/github.com/kevholditch/gokong/certificates.go new file mode 100644 index 00000000..4bcf8366 --- /dev/null +++ b/vendor/github.com/kevholditch/gokong/certificates.go @@ -0,0 +1,116 @@ +package gokong + +import ( + "encoding/json" + "fmt" + "github.com/parnurzeal/gorequest" +) + +type CertificateClient struct { + config *Config + client *gorequest.SuperAgent +} + +type CertificateRequest struct { + Cert string `json:"cert,omitempty"` + Key string `json:"key,omitempty"` +} + +type Certificate struct { + Id string `json:"id,omitempty"` + Cert string `json:"cert,omitempty"` + Key string `json:"key,omitempty"` +} + +type Certificates struct { + Results []*Certificate `json:"data,omitempty"` + Total int `json:"total,omitempty"` +} + +const CertificatesPath = "/certificates/" + +func (certificateClient *CertificateClient) GetById(id string) (*Certificate, error) { + + _, body, errs := certificateClient.client.Get(certificateClient.config.HostAddress + CertificatesPath + id).End() + if errs != nil { + return nil, fmt.Errorf("could not get certificate, error: %v", errs) + } + + certificate := &Certificate{} + err := json.Unmarshal([]byte(body), certificate) + if err != nil { + return nil, fmt.Errorf("could not parse certificate get response, error: %v", err) + } + + if certificate.Id == "" { + return nil, nil + } + + return certificate, nil +} + +func (certificateClient *CertificateClient) Create(certificateRequest *CertificateRequest) (*Certificate, error) { + + _, body, errs := certificateClient.client.Post(certificateClient.config.HostAddress + CertificatesPath).Send(certificateRequest).End() + if errs != nil { + return nil, fmt.Errorf("could not create new certificate, error: %v", errs) + } + + createdCertificate := &Certificate{} + err := json.Unmarshal([]byte(body), createdCertificate) + if err != nil { + return nil, fmt.Errorf("could not parse certificate creation response, error: %v", err) + } + + if createdCertificate.Id == "" { + return nil, fmt.Errorf("could not create certificate, error: %v", body) + } + + return createdCertificate, nil +} + +func (certificateClient *CertificateClient) DeleteById(id string) error { + + res, _, errs := certificateClient.client.Delete(certificateClient.config.HostAddress + CertificatesPath + id).End() + if errs != nil { + return fmt.Errorf("could not delete certificate, result: %v error: %v", res, errs) + } + + return nil +} + +func (certificateClient *CertificateClient) List() (*Certificates, error) { + + _, body, errs := certificateClient.client.Get(certificateClient.config.HostAddress + CertificatesPath).End() + if errs != nil { + return nil, fmt.Errorf("could not get certificates, error: %v", errs) + } + + certificates := &Certificates{} + err := json.Unmarshal([]byte(body), certificates) + if err != nil { + return nil, fmt.Errorf("could not parse certificates list response, error: %v", err) + } + + return certificates, nil +} + +func (certificateClient *CertificateClient) UpdateById(id string, certificateRequest *CertificateRequest) (*Certificate, error) { + + _, body, errs := certificateClient.client.Patch(certificateClient.config.HostAddress + CertificatesPath + id).Send(certificateRequest).End() + if errs != nil { + return nil, fmt.Errorf("could not update certificate, error: %v", errs) + } + + updatedCertificate := &Certificate{} + err := json.Unmarshal([]byte(body), updatedCertificate) + if err != nil { + return nil, fmt.Errorf("could not parse certificate update response, error: %v", err) + } + + if updatedCertificate.Id == "" { + return nil, fmt.Errorf("could not update certificate, error: %v", body) + } + + return updatedCertificate, nil +} diff --git a/vendor/github.com/kevholditch/gokong/client.go b/vendor/github.com/kevholditch/gokong/client.go index d644ac00..aad5c7ae 100644 --- a/vendor/github.com/kevholditch/gokong/client.go +++ b/vendor/github.com/kevholditch/gokong/client.go @@ -80,3 +80,31 @@ func (kongAdminClient *KongAdminClient) Consumers() *ConsumerClient { client: kongAdminClient.client, } } + +func (kongAdminClient *KongAdminClient) Plugins() *PluginClient { + return &PluginClient{ + config: kongAdminClient.config, + client: kongAdminClient.client, + } +} + +func (kongAdminClient *KongAdminClient) Certificates() *CertificateClient { + return &CertificateClient{ + config: kongAdminClient.config, + client: kongAdminClient.client, + } +} + +func (kongAdminClient *KongAdminClient) Snis() *SnisClient { + return &SnisClient{ + config: kongAdminClient.config, + client: kongAdminClient.client, + } +} + +func (kongAdminClient *KongAdminClient) Upstreams() *UpstreamClient { + return &UpstreamClient{ + config: kongAdminClient.config, + client: kongAdminClient.client, + } +} diff --git a/vendor/github.com/kevholditch/gokong/consumers.go b/vendor/github.com/kevholditch/gokong/consumers.go index 3430734c..33bb2289 100644 --- a/vendor/github.com/kevholditch/gokong/consumers.go +++ b/vendor/github.com/kevholditch/gokong/consumers.go @@ -62,9 +62,9 @@ func (consumerClient *ConsumerClient) GetById(id string) (*Consumer, error) { return consumer, nil } -func (consumerClient *ConsumerClient) Create(newConsumer *ConsumerRequest) (*Consumer, error) { +func (consumerClient *ConsumerClient) Create(consumerRequest *ConsumerRequest) (*Consumer, error) { - _, body, errs := consumerClient.client.Post(consumerClient.config.HostAddress + ConsumersPath).Send(newConsumer).End() + _, body, errs := consumerClient.client.Post(consumerClient.config.HostAddress + ConsumersPath).Send(consumerRequest).End() if errs != nil { return nil, fmt.Errorf("could not create new consumer, error: %v", errs) } @@ -75,6 +75,10 @@ func (consumerClient *ConsumerClient) Create(newConsumer *ConsumerRequest) (*Con return nil, fmt.Errorf("could not parse consumer creation response, error: %v", err) } + if createdConsumer.Id == "" { + return nil, fmt.Errorf("could not create consumer, error: %v", body) + } + return createdConsumer, nil } @@ -135,5 +139,9 @@ func (consumerClient *ConsumerClient) UpdateById(id string, consumerRequest *Con return nil, fmt.Errorf("could not parse consumer update response, error: %v", err) } + if updatedConsumer.Id == "" { + return nil, fmt.Errorf("could not update consumer, error: %v", body) + } + return updatedConsumer, nil } diff --git a/vendor/github.com/kevholditch/gokong/plugins.go b/vendor/github.com/kevholditch/gokong/plugins.go new file mode 100644 index 00000000..bed0c149 --- /dev/null +++ b/vendor/github.com/kevholditch/gokong/plugins.go @@ -0,0 +1,141 @@ +package gokong + +import ( + "encoding/json" + "fmt" + "github.com/parnurzeal/gorequest" +) + +type PluginClient struct { + config *Config + client *gorequest.SuperAgent +} + +type PluginRequest struct { + Name string `json:"name"` + ApiId string `json:"api_id,omitempty"` + ConsumerId string `json:"consumer_id,omitempty"` + Config map[string]interface{} `json:"config,omitempty"` +} + +type Plugin struct { + Id string `json:"id"` + Name string `json:"name"` + ApiId string `json:"api_id,omitempty"` + ConsumerId string `json:"consumer_id,omitempty"` + Config map[string]interface{} `json:"config,omitempty"` + Enabled bool `json:"enabled,omitempty"` +} + +type Plugins struct { + Results []*Plugin `json:"data,omitempty"` + Total int `json:"total,omitempty"` + Next string `json:"next,omitempty"` +} + +type PluginFilter struct { + Id string `url:"id,omitempty"` + Name string `url:"name,omitempty"` + ApiId string `url:"api_id,omitempty"` + ConsumerId string `url:"consumer_id,omitempty"` + Size int `url:"size,omitempty"` + Offset int `url:"offset,omitempty"` +} + +const PluginsPath = "/plugins/" + +func (pluginClient *PluginClient) GetById(id string) (*Plugin, error) { + + _, body, errs := pluginClient.client.Get(pluginClient.config.HostAddress + PluginsPath + id).End() + if errs != nil { + return nil, fmt.Errorf("could not get plugin, error: %v", errs) + } + + plugin := &Plugin{} + err := json.Unmarshal([]byte(body), plugin) + if err != nil { + return nil, fmt.Errorf("could not parse plugin plugin response, error: %v", err) + } + + if plugin.Id == "" { + return nil, nil + } + + return plugin, nil +} + +func (pluginClient *PluginClient) List() (*Plugins, error) { + return pluginClient.ListFiltered(nil) +} + +func (pluginClient *PluginClient) ListFiltered(filter *PluginFilter) (*Plugins, error) { + + address, err := addQueryString(pluginClient.config.HostAddress+PluginsPath, filter) + + if err != nil { + return nil, fmt.Errorf("could not build query string for plugins filter, error: %v", err) + } + + _, body, errs := pluginClient.client.Get(address).End() + if errs != nil { + return nil, fmt.Errorf("could not get plugins, error: %v", errs) + } + + plugins := &Plugins{} + err = json.Unmarshal([]byte(body), plugins) + if err != nil { + return nil, fmt.Errorf("could not parse plugins list response, error: %v", err) + } + + return plugins, nil +} + +func (pluginClient *PluginClient) Create(pluginRequest *PluginRequest) (*Plugin, error) { + + _, body, errs := pluginClient.client.Post(pluginClient.config.HostAddress + PluginsPath).Send(pluginRequest).End() + if errs != nil { + return nil, fmt.Errorf("could not create new plugin, error: %v", errs) + } + + createdPlugin := &Plugin{} + err := json.Unmarshal([]byte(body), createdPlugin) + if err != nil { + return nil, fmt.Errorf("could not parse plugin creation response, error: %v", err) + } + + if createdPlugin.Id == "" { + return nil, fmt.Errorf("could not create plugin, err: %v", body) + } + + return createdPlugin, nil +} + +func (pluginClient *PluginClient) UpdateById(id string, pluginRequest *PluginRequest) (*Plugin, error) { + + _, body, errs := pluginClient.client.Patch(pluginClient.config.HostAddress + PluginsPath + id).Send(pluginRequest).End() + if errs != nil { + return nil, fmt.Errorf("could not update plugin, error: %v", errs) + } + + updatedPlugin := &Plugin{} + err := json.Unmarshal([]byte(body), updatedPlugin) + if err != nil { + return nil, fmt.Errorf("could not parse plugin update response, error: %v", err) + } + + if updatedPlugin.Id == "" { + return nil, fmt.Errorf("could not update plugin, error: %v", body) + } + + return updatedPlugin, nil +} + +func (pluginClient *PluginClient) DeleteById(id string) error { + + res, _, errs := pluginClient.client.Delete(pluginClient.config.HostAddress + PluginsPath + id).End() + if errs != nil { + return fmt.Errorf("could not delete plugin, result: %v error: %v", res, errs) + } + + return nil +} diff --git a/vendor/github.com/kevholditch/gokong/snis.go b/vendor/github.com/kevholditch/gokong/snis.go new file mode 100644 index 00000000..0328732c --- /dev/null +++ b/vendor/github.com/kevholditch/gokong/snis.go @@ -0,0 +1,115 @@ +package gokong + +import ( + "encoding/json" + "fmt" + "github.com/parnurzeal/gorequest" +) + +type SnisClient struct { + config *Config + client *gorequest.SuperAgent +} + +type SnisRequest struct { + Name string `json:"name,omitempty"` + SslCertificateId string `json:"ssl_certificate_id,omitempty"` +} + +type Sni struct { + Name string `json:"name,omitempty"` + SslCertificateId string `json:"ssl_certificate_id,omitempty"` +} + +type Snis struct { + Results []*Sni `json:"data,omitempty"` + Total int `json:"total,omitempty"` +} + +const SnisPath = "/snis/" + +func (snisClient *SnisClient) Create(snisRequest *SnisRequest) (*Sni, error) { + + _, body, errs := snisClient.client.Post(snisClient.config.HostAddress + SnisPath).Send(snisRequest).End() + if errs != nil { + return nil, fmt.Errorf("could not create new sni, error: %v", errs) + } + + sni := &Sni{} + err := json.Unmarshal([]byte(body), sni) + if err != nil { + return nil, fmt.Errorf("could not parse sni creation response, error: %v", err) + } + + if sni.SslCertificateId == "" { + return nil, fmt.Errorf("could not create sni, error: %v", body) + } + + return sni, nil +} + +func (snisClient *SnisClient) GetByName(name string) (*Sni, error) { + + _, body, errs := snisClient.client.Get(snisClient.config.HostAddress + SnisPath + name).End() + if errs != nil { + return nil, fmt.Errorf("could not get sni, error: %v", errs) + } + + sni := &Sni{} + err := json.Unmarshal([]byte(body), sni) + if err != nil { + return nil, fmt.Errorf("could not parse sni get response, error: %v", err) + } + + if sni.Name == "" { + return nil, nil + } + + return sni, nil +} + +func (snisClient *SnisClient) List() (*Snis, error) { + + _, body, errs := snisClient.client.Get(snisClient.config.HostAddress + SnisPath).End() + if errs != nil { + return nil, fmt.Errorf("could not get snis, error: %v", errs) + } + + snis := &Snis{} + err := json.Unmarshal([]byte(body), snis) + if err != nil { + return nil, fmt.Errorf("could not parse snis list response, error: %v", err) + } + + return snis, nil +} + +func (snisClient *SnisClient) DeleteByName(name string) error { + + res, _, errs := snisClient.client.Delete(snisClient.config.HostAddress + SnisPath + name).End() + if errs != nil { + return fmt.Errorf("could not delete sni, result: %v error: %v", res, errs) + } + + return nil +} + +func (snisClient *SnisClient) UpdateByName(name string, snisRequest *SnisRequest) (*Sni, error) { + + _, body, errs := snisClient.client.Patch(snisClient.config.HostAddress + SnisPath + name).Send(snisRequest).End() + if errs != nil { + return nil, fmt.Errorf("could not update sni, error: %v", errs) + } + + updatedSni := &Sni{} + err := json.Unmarshal([]byte(body), updatedSni) + if err != nil { + return nil, fmt.Errorf("could not parse sni update response, error: %v", err) + } + + if updatedSni.SslCertificateId == "" { + return nil, fmt.Errorf("could not update sni, error: %v", body) + } + + return updatedSni, nil +} diff --git a/vendor/github.com/kevholditch/gokong/upstreams.go b/vendor/github.com/kevholditch/gokong/upstreams.go new file mode 100644 index 00000000..5b58f760 --- /dev/null +++ b/vendor/github.com/kevholditch/gokong/upstreams.go @@ -0,0 +1,150 @@ +package gokong + +import ( + "encoding/json" + "fmt" + "github.com/parnurzeal/gorequest" +) + +type UpstreamClient struct { + config *Config + client *gorequest.SuperAgent +} + +type UpstreamRequest struct { + Name string `json:"name,omitempty"` + Slots int `json:"slots,omitempty"` + OrderList []int `json:"orderlist,omitempty"` +} + +type Upstream struct { + Id string `json:"id,omitempty"` + Name string `json:"name,omitempty"` + Slots int `json:"slots,omitempty"` + OrderList []int `json:"orderlist,omitempty"` +} + +type Upstreams struct { + Results []*Upstream `json:"data,omitempty"` + Total int `json:"total,omitempty"` + Next string `json:"next,omitempty"` + Offset string `json:"offset,omitempty"` +} + +type UpstreamFilter struct { + Id string `url:"id,omitempty"` + Name string `url:"name,omitempty"` + Slots int `url:"slots,omitempty"` + Size int `url:"size,omitempty"` + Offset int `url:"offset,omitempty"` +} + +const UpstreamsPath = "/upstreams/" + +func (upstreamClient *UpstreamClient) GetByName(name string) (*Upstream, error) { + return upstreamClient.GetById(name) +} + +func (upstreamClient *UpstreamClient) GetById(id string) (*Upstream, error) { + + _, body, errs := upstreamClient.client.Get(upstreamClient.config.HostAddress + UpstreamsPath + id).End() + if errs != nil { + return nil, fmt.Errorf("could not get upstream, error: %v", errs) + } + + upstream := &Upstream{} + err := json.Unmarshal([]byte(body), upstream) + if err != nil { + return nil, fmt.Errorf("could not parse upstream get response, error: %v", err) + } + + if upstream.Id == "" { + return nil, nil + } + + return upstream, nil +} + +func (upstreamClient *UpstreamClient) Create(upstreamRequest *UpstreamRequest) (*Upstream, error) { + + _, body, errs := upstreamClient.client.Post(upstreamClient.config.HostAddress + UpstreamsPath).Send(upstreamRequest).End() + if errs != nil { + return nil, fmt.Errorf("could not create new upstream, error: %v", errs) + } + + createdUpstream := &Upstream{} + err := json.Unmarshal([]byte(body), createdUpstream) + if err != nil { + return nil, fmt.Errorf("could not parse upstream creation response, error: %v", err) + } + + if createdUpstream.Id == "" { + return nil, fmt.Errorf("could not create update, error: %v", body) + } + + return createdUpstream, nil +} + +func (upstreamClient *UpstreamClient) DeleteByName(name string) error { + return upstreamClient.DeleteById(name) +} + +func (upstreamClient *UpstreamClient) DeleteById(id string) error { + + res, _, errs := upstreamClient.client.Delete(upstreamClient.config.HostAddress + UpstreamsPath + id).End() + if errs != nil { + return fmt.Errorf("could not delete upstream, result: %v error: %v", res, errs) + } + + return nil +} + +func (upstreamClient *UpstreamClient) List() (*Upstreams, error) { + return upstreamClient.ListFiltered(nil) +} + +func (upstreamClient *UpstreamClient) ListFiltered(filter *UpstreamFilter) (*Upstreams, error) { + + address, err := addQueryString(upstreamClient.config.HostAddress+UpstreamsPath, filter) + + if err != nil { + return nil, fmt.Errorf("could not build query string for upstreams filter, error: %v", err) + } + + _, body, errs := upstreamClient.client.Get(address).End() + if errs != nil { + return nil, fmt.Errorf("could not get upstreams, error: %v", errs) + } + + upstreams := &Upstreams{} + err = json.Unmarshal([]byte(body), upstreams) + if err != nil { + return nil, fmt.Errorf("could not parse upstreams list response, error: %v", err) + } + + return upstreams, nil +} + +func (upstreamClient *UpstreamClient) UpdateByName(name string, upstreamRequest *UpstreamRequest) (*Upstream, error) { + return upstreamClient.UpdateById(name, upstreamRequest) +} + +func (upstreamClient *UpstreamClient) UpdateById(id string, upstreamRequest *UpstreamRequest) (*Upstream, error) { + + _, body, errs := upstreamClient.client.Patch(upstreamClient.config.HostAddress + UpstreamsPath + id).Send(upstreamRequest).End() + if errs != nil { + return nil, fmt.Errorf("could not update upstream, error: %v", errs) + } + + updatedUpstream := &Upstream{} + err := json.Unmarshal([]byte(body), updatedUpstream) + if err != nil { + return nil, fmt.Errorf("could not parse upstream update response, error: %v", err) + } + + if updatedUpstream.Id == "" { + return nil, fmt.Errorf("could not update upstream, error: %v", body) + } + + return updatedUpstream, nil +} diff --git a/vendor/vendor.json b/vendor/vendor.json index cba82b25..cb47845e 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -535,10 +535,10 @@ "revisionTime": "2016-08-03T19:07:31Z" }, { - "checksumSHA1": "hk1rMY2/nCmOOnZUMPFAyiVdLbo=", + "checksumSHA1": "yJ7hJnL5e7BDSqxS/3asGqhzu78=", "path": "github.com/kevholditch/gokong", - "revision": "4f61213b7d26367c6dd7f15abef5394a41ff26d1", - "revisionTime": "2017-11-23T20:03:07Z" + "revision": "5c1e77510a1872e3ab2a19293d615f4b0702e534", + "revisionTime": "2017-11-29T22:50:42Z" }, { "path": "github.com/kevholditch/gokong...", @@ -547,8 +547,8 @@ { "checksumSHA1": "zrebs2M5FR95Rz1khq60RjMd+HY=", "path": "github.com/kevholditch/gokong/containers", - "revision": "4f61213b7d26367c6dd7f15abef5394a41ff26d1", - "revisionTime": "2017-11-23T20:03:07Z" + "revision": "5c1e77510a1872e3ab2a19293d615f4b0702e534", + "revisionTime": "2017-11-29T22:50:42Z" }, { "checksumSHA1": "IfZcD4U1dtllJKlPNeD2aU4Jn98=",