Skip to content

Commit

Permalink
Feat: support provider registry (#653)
Browse files Browse the repository at this point in the history
* Feat: support provider registry

* Fixed test

* minor changes based on PR feedback
  • Loading branch information
TomerHeber committed May 24, 2023
1 parent d0d40c1 commit b670988
Show file tree
Hide file tree
Showing 15 changed files with 857 additions and 1 deletion.
5 changes: 5 additions & 0 deletions client/api_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,11 @@ type ApiClientInterface interface {
GpgKeyCreate(payload *GpgKeyCreatePayload) (*GpgKey, error)
GpgKeyDelete(id string) error
GpgKeys() ([]GpgKey, error)
ProviderCreate(payload ProviderCreatePayload) (*Provider, error)
Provider(providerId string) (*Provider, error)
ProviderDelete(providerId string) error
ProviderUpdate(providerId string, payload ProviderUpdatePayload) (*Provider, error)
Providers() ([]Provider, error)
}

func NewApiClient(client http.HttpClientInterface, defaultOrganizationId string) ApiClientInterface {
Expand Down
74 changes: 74 additions & 0 deletions client/api_client_mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

74 changes: 74 additions & 0 deletions client/provider.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package client

type Provider struct {
Id string `json:"id"`
Type string `json:"type"`
Description string `json:"description"`
}

type ProviderCreatePayload struct {
Type string `json:"type"`
Description string `json:"description"`
}

type ProviderUpdatePayload struct {
Description string `json:"description"`
}

func (client *ApiClient) ProviderCreate(payload ProviderCreatePayload) (*Provider, error) {
organizationId, err := client.OrganizationId()
if err != nil {
return nil, err
}

payloadWithOrganizationId := struct {
ProviderCreatePayload
OrganizationId string `json:"organizationId"`
}{
payload,
organizationId,
}

var result Provider
if err := client.http.Post("/providers", payloadWithOrganizationId, &result); err != nil {
return nil, err
}

return &result, nil
}

func (client *ApiClient) Provider(providerId string) (*Provider, error) {
var result Provider
if err := client.http.Get("/providers/"+providerId, nil, &result); err != nil {
return nil, err
}

return &result, nil
}

func (client *ApiClient) ProviderDelete(providerId string) error {
return client.http.Delete("/providers/" + providerId)
}

func (client *ApiClient) ProviderUpdate(providerId string, payload ProviderUpdatePayload) (*Provider, error) {
var result Provider
if err := client.http.Put("/providers/"+providerId, payload, &result); err != nil {
return nil, err
}

return &result, nil
}

func (client *ApiClient) Providers() ([]Provider, error) {
organizationId, err := client.OrganizationId()
if err != nil {
return nil, err
}

var result []Provider
if err := client.http.Get("/providers", map[string]string{"organizationId": organizationId}, &result); err != nil {
return nil, err
}

return result, err
}
115 changes: 115 additions & 0 deletions client/provider_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package client_test

import (
. "github.com/env0/terraform-provider-env0/client"
"github.com/golang/mock/gomock"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)

var _ = Describe("Provider Client", func() {
mockProvider := Provider{
Id: "id",
Type: "type",
Description: "description",
}

Describe("Get Provider", func() {
var returnedProvider *Provider

BeforeEach(func() {
httpCall = mockHttpClient.EXPECT().
Get("/providers/"+mockProvider.Id, gomock.Nil(), gomock.Any()).
Do(func(path string, request interface{}, response *Provider) {
*response = mockProvider
}).Times(1)
returnedProvider, _ = apiClient.Provider(mockProvider.Id)
})

It("Should return provider", func() {
Expect(*returnedProvider).To(Equal(mockProvider))
})
})

Describe("Get All Providers", func() {
var returnedProviders []Provider
mockProviders := []Provider{mockProvider}

BeforeEach(func() {
mockOrganizationIdCall(organizationId).Times(1)
httpCall = mockHttpClient.EXPECT().
Get("/providers", map[string]string{"organizationId": organizationId}, gomock.Any()).
Do(func(path string, request interface{}, response *[]Provider) {
*response = mockProviders
}).Times(1)
returnedProviders, _ = apiClient.Providers()
})

It("Should return providers", func() {
Expect(returnedProviders).To(Equal(mockProviders))
})
})

Describe("Create Provider", func() {
var createdProvider *Provider

BeforeEach(func() {
mockOrganizationIdCall(organizationId).Times(1)

createProviderPayload := ProviderCreatePayload{
Type: mockProvider.Type,
Description: mockProvider.Description,
}

expectedCreateRequest := struct {
ProviderCreatePayload
OrganizationId string `json:"organizationId"`
}{
createProviderPayload,
organizationId,
}

httpCall = mockHttpClient.EXPECT().
Post("/providers", expectedCreateRequest, gomock.Any()).
Do(func(path string, request interface{}, response *Provider) {
*response = mockProvider
}).Times(1)

createdProvider, _ = apiClient.ProviderCreate(createProviderPayload)
})
It("Should return created provider", func() {
Expect(*createdProvider).To(Equal(mockProvider))
})
})

Describe("Delete Provider", func() {
BeforeEach(func() {
httpCall = mockHttpClient.EXPECT().Delete("/providers/" + mockProvider.Id).Times(1)
apiClient.ProviderDelete(mockProvider.Id)
})

It("Should send DELETE request with provider id", func() {})
})

Describe("Update Provider", func() {
var updatedProvider *Provider

updatedMockProvider := mockProvider
updatedMockProvider.Description = "new-description"

BeforeEach(func() {
updateProviderPayload := ProviderUpdatePayload{Description: updatedMockProvider.Description}
httpCall = mockHttpClient.EXPECT().
Put("/providers/"+mockProvider.Id, updateProviderPayload, gomock.Any()).
Do(func(path string, request interface{}, response *Provider) {
*response = updatedMockProvider
}).Times(1)

updatedProvider, _ = apiClient.ProviderUpdate(mockProvider.Id, updateProviderPayload)
})

It("Should return updated provider received from API", func() {
Expect(*updatedProvider).To(Equal(updatedMockProvider))
})
})
})
58 changes: 58 additions & 0 deletions env0/data_provider.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package env0

import (
"context"

"github.com/env0/terraform-provider-env0/client"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

func dataProvider() *schema.Resource {
return &schema.Resource{
ReadContext: dataProviderRead,

Schema: map[string]*schema.Schema{
"type": {
Type: schema.TypeString,
Description: "the type/name of the provider",
Optional: true,
ExactlyOneOf: []string{"type", "id"},
},
"id": {
Type: schema.TypeString,
Description: "id of the provider",
Optional: true,
ExactlyOneOf: []string{"type", "id"},
},
"description": {
Type: schema.TypeString,
Description: "the description of the provider",
Computed: true,
},
},
}
}

func dataProviderRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
var provider *client.Provider
var err error

id, ok := d.GetOk("id")
if ok {
provider, err = meta.(client.ApiClientInterface).Provider(id.(string))
} else {
name := d.Get("type").(string)
provider, err = getProviderByName(name, meta)
}

if err != nil {
return DataGetFailure("provider", id, err)
}

if err := writeResourceData(provider, d); err != nil {
return diag.Errorf("schema resource data serialization failed: %v", err)
}

return nil
}
Loading

0 comments on commit b670988

Please sign in to comment.