Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add CustomConfig for Private Links #117

Merged
merged 2 commits into from
Oct 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,15 @@ 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/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased](https://github.com/fivetran/go-fivetran/compare/v1.0.1...HEAD)
## [Unreleased](https://github.com/fivetran/go-fivetran/compare/v1.0.2...HEAD)

## [1.0.2](https://github.com/fivetran/go-fivetran/compare/v1.0.1...v1.0.2)

## Added
Support for custom config (`map[string]interface{}`) for private links:
- `PrivateLinkCreateService.ConfigCustom` and `PrivateLinkCreateService.DoCustom` methods
- `PrivateLinkModifyService.ConfigCustom` and `PrivateLinkModifyService.DoCustom` methods
- `PrivateLinkDetailsService.DoCustom` method

## [1.0.1](https://github.com/fivetran/go-fivetran/compare/v1.0.0...v1.0.1)

Expand Down
2 changes: 1 addition & 1 deletion client.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ const defaultBaseURL = "https://api.fivetran.com/v1"
const restAPIv2 = "application/json;version=2"

// WARNING: Update Agent version on each release!
const defaultUserAgent = "Go-Fivetran/0.9.4"
const defaultUserAgent = "Go-Fivetran/1.0.2"

// New receives API Key and API Secret, and returns a new Client with the
// default HTTP client
Expand Down
34 changes: 33 additions & 1 deletion private_link/common_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,25 @@ type PrivateLinkResponse struct {
} `json:"data"`
}

type PrivateLinkCustomResponse struct {
Code string `json:"code"`
Message string `json:"message"`
Data struct {
PrivateLinkResponseBase
Config map[string]interface{} `json:"config"`
} `json:"data"`
}

type PrivateLinkCustomMergedResponse struct {
Code string `json:"code"`
Message string `json:"message"`
Data struct {
PrivateLinkResponseBase
CustomConfig map[string]interface{} `json:"config"`
Config PrivateLinkConfigResponse // no mapping here
} `json:"data"`
}

type PrivateLinkListResponse struct {
Code string `json:"code"`
Data struct {
Expand All @@ -30,13 +49,26 @@ type PrivateLinkListResponse struct {
} `json:"data"`
}

type privateLinkCreateRequest struct {
type privateLinkCreateRequestBase struct {
Name *string `json:"name,omitempty"`
Region *string `json:"region,omitempty"`
Service *string `json:"service,omitempty"`
}

type privateLinkCreateRequest struct {
privateLinkCreateRequestBase
Config any `json:"config,omitempty"`
}

type privateLinkCustomCreateRequest struct {
privateLinkCreateRequestBase
Config *map[string]interface{} `json:"config,omitempty"`
}

type privateLinkModifyRequest struct {
Config any `json:"config,omitempty"`
}

type privateLinkCustomModifyRequest struct {
Config *map[string]interface{} `json:"config,omitempty"`
}
10 changes: 10 additions & 0 deletions private_link/private_link_config.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package privatelink

import "github.com/fivetran/go-fivetran/utils"

// PrivateLinkConfig builds Private Link Management, Private Link Config.
// Ref. https://fivetran.com/docs/rest-api/private-link-management#privatelinketupconfigurations
type PrivateLinkConfig struct {
Expand Down Expand Up @@ -65,6 +67,14 @@ func (plc *PrivateLinkConfig) Request() *privateLinkConfigRequest {
}
}

func (plc *PrivateLinkConfig) Merge(customConfig *map[string]interface{}) (*map[string]interface{}, error) {
err := utils.MergeIntoMap(plc.Request(), customConfig)
if err != nil {
return nil, err
}
return customConfig, nil
}

func (plc *PrivateLinkConfig) ConnectionServiceName(value string) *PrivateLinkConfig {
plc.connectionServiceName = &value
return plc
Expand Down
86 changes: 79 additions & 7 deletions private_link/private_link_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"

httputils "github.com/fivetran/go-fivetran/http_utils"
"github.com/fivetran/go-fivetran/utils"
)

// PrivateLinkCreateService implements the Log Management, Create a Log Service API.
Expand All @@ -14,23 +15,56 @@ type PrivateLinkCreateService struct {
region *string
service *string
config *PrivateLinkConfig
configCustom *map[string]interface{}
}


func (s *PrivateLinkCreateService) request() privateLinkCreateRequest {
func (s *PrivateLinkCreateService) requestBase() privateLinkCreateRequestBase {
return privateLinkCreateRequestBase{
Name: s.name,
Region: s.region,
Service: s.service,
}
}

func (s *PrivateLinkCreateService) request() *privateLinkCreateRequest {
var config interface{}
if s.config != nil {
config = s.config.Request()
}

return privateLinkCreateRequest{
Name: s.name,
Region: s.region,
Service: s.service,
Config: config,
r := &privateLinkCreateRequest{
privateLinkCreateRequestBase: s.requestBase(),
Config: config,
}

return r
}

func (s *PrivateLinkCreateService) requestCustom() *privateLinkCustomCreateRequest {
return &privateLinkCustomCreateRequest{
privateLinkCreateRequestBase: s.requestBase(),
Config: s.configCustom,
}
}

func (s *PrivateLinkCreateService) requestCustomMerged() (*privateLinkCustomCreateRequest, error) {
currentConfig := s.configCustom

if s.config != nil {
var err error
currentConfig, err = s.config.Merge(currentConfig)
if err != nil {
return nil, err
}
}

return &privateLinkCustomCreateRequest{
privateLinkCreateRequestBase: s.requestBase(),
Config: currentConfig,
}, nil
}

func (s *PrivateLinkCreateService) Region(value string) *PrivateLinkCreateService {
s.region = &value
return s
Expand All @@ -51,8 +85,46 @@ func (s *PrivateLinkCreateService) Config(value *PrivateLinkConfig) *PrivateLink
return s
}

func (s *PrivateLinkCreateService) ConfigCustom(value *map[string]interface{}) *PrivateLinkCreateService {
s.configCustom = value
return s
}

func (s *PrivateLinkCreateService) do(ctx context.Context, req, response any) error {
err := s.HttpService.Do(ctx, "POST", "/private-links", s.request(), nil, 201, &response)
return err
}

func (s *PrivateLinkCreateService) Do(ctx context.Context) (PrivateLinkResponse, error) {
var response PrivateLinkResponse
err := s.HttpService.Do(ctx, "POST", "/private-links", s.request(), nil, 201, &response)

err := s.do(ctx, s.request(), &response)

return response, err
}

func (s *PrivateLinkCreateService) DoCustom(ctx context.Context) (PrivateLinkCustomResponse, error) {
var response PrivateLinkCustomResponse

err := s.do(ctx, s.requestCustom(), &response)

return response, err
}

func (s *PrivateLinkCreateService) DoCustomMerged(ctx context.Context) (PrivateLinkCustomMergedResponse, error) {
var response PrivateLinkCustomMergedResponse

req, err := s.requestCustomMerged()

if err != nil {
return response, err
}

err = s.do(ctx, req, &response)

if err == nil {
err = utils.FetchFromMap(&response.Data.CustomConfig, &response.Data.Config)
}

return response, err
}
11 changes: 11 additions & 0 deletions private_link/private_link_details.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,17 @@ func (s *PrivateLinkDetailsService) Do(ctx context.Context) (PrivateLinkResponse
return response, fmt.Errorf("missing required privateLinkId")
}

url := fmt.Sprintf("/private-links/%v", *s.privateLinkId)
err := s.HttpService.Do(ctx, "GET", url, nil, nil, 200, &response)
return response, err
}

func (s *PrivateLinkDetailsService) DoCustom(ctx context.Context) (PrivateLinkCustomResponse, error) {
var response PrivateLinkCustomResponse
if s.privateLinkId == nil {
return response, fmt.Errorf("missing required privateLinkId")
}

url := fmt.Sprintf("/private-links/%v", *s.privateLinkId)
err := s.HttpService.Do(ctx, "GET", url, nil, nil, 200, &response)
return response, err
Expand Down
49 changes: 45 additions & 4 deletions private_link/private_link_details_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ func TestPrivateLinkDetailsServiceDo(t *testing.T) {
// arrange

ftClient, mockClient := testutils.CreateTestClient()
handler := mockClient.When(http.MethodGet, "/v1/private-links/123456").
handler := mockClient.When(http.MethodGet, "/v1/private-links/private_link_id").
ThenCall(func(req *http.Request) (*http.Response, error) {
response := mock.NewResponse(req, http.StatusOK, preparePrivateLinkDetailsResponse())
return response, nil
})

// act
response, err := ftClient.NewPrivateLinkDetails().
PrivateLinkId("123456").
PrivateLinkId("private_link_id").
Do(context.Background())

// assert
Expand All @@ -36,11 +36,38 @@ func TestPrivateLinkDetailsServiceDo(t *testing.T) {
assertPrivateLinkDetailsResponse(t, response)
}

func TestPrivateLinkDetailsCustomServiceDo(t *testing.T) {
// arrange

ftClient, mockClient := testutils.CreateTestClient()
handler := mockClient.When(http.MethodGet, "/v1/private-links/private_link_id").
ThenCall(func(req *http.Request) (*http.Response, error) {
response := mock.NewResponse(req, http.StatusOK, preparePrivateLinkDetailsResponse())
return response, nil
})

// act
response, err := ftClient.NewPrivateLinkDetails().
PrivateLinkId("private_link_id").
DoCustom(context.Background())

// assert
if err != nil {
t.Error(err)
}

interactions := mockClient.Interactions()
testutils.AssertEqual(t, len(interactions), 1)
testutils.AssertEqual(t, interactions[0].Handler, handler)
testutils.AssertEqual(t, handler.Interactions, 1)
assertPrivateLinkCustomDetailsResponse(t, response)
}

func preparePrivateLinkDetailsResponse() string {
return `{
"code": "Success",
"data": {
"id": "123456",
"id": "private_link_id",
"name": "name",
"region": "region",
"service": "service",
Expand All @@ -59,7 +86,7 @@ func preparePrivateLinkDetailsResponse() string {

func assertPrivateLinkDetailsResponse(t *testing.T, response privatelink.PrivateLinkResponse) {
testutils.AssertEqual(t, response.Code, "Success")
testutils.AssertEqual(t, response.Data.Id, "123456")
testutils.AssertEqual(t, response.Data.Id, "private_link_id")
testutils.AssertEqual(t, response.Data.Name, "name")
testutils.AssertEqual(t, response.Data.Region, "region")
testutils.AssertEqual(t, response.Data.Service, "service")
Expand All @@ -70,3 +97,17 @@ func assertPrivateLinkDetailsResponse(t *testing.T, response privatelink.Private
testutils.AssertEqual(t, response.Data.CreatedBy, "created_by")
testutils.AssertEqual(t, response.Data.Config.ConnectionServiceName, "connection_service_name")
}

func assertPrivateLinkCustomDetailsResponse(t *testing.T, response privatelink.PrivateLinkCustomResponse) {
testutils.AssertEqual(t, response.Code, "Success")
testutils.AssertEqual(t, response.Data.Id, "private_link_id")
testutils.AssertEqual(t, response.Data.Name, "name")
testutils.AssertEqual(t, response.Data.Region, "region")
testutils.AssertEqual(t, response.Data.Service, "service")
testutils.AssertEqual(t, response.Data.CloudProvider, "cloud_provider")
testutils.AssertEqual(t, response.Data.State, "state")
testutils.AssertEqual(t, response.Data.StateSummary, "state_summary")
testutils.AssertEqual(t, response.Data.CreatedAt, "2022-04-29T09:41:08.583Z")
testutils.AssertEqual(t, response.Data.CreatedBy, "created_by")
testutils.AssertEqual(t, response.Data.Config["connection_service_name"], "connection_service_name")
}
Loading
Loading