diff --git a/CHANGELOG.md b/CHANGELOG.md index 5617f5cb..2a307eeb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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/v0.8.1...HEAD) +## [Unreleased](https://github.com/fivetran/go-fivetran/compare/v0.8.2...HEAD) + +## [0.8.2](https://github.com/fivetran/go-fivetran/compare/v0.8.1...v0.8.2) + +## Added +Support for custom config (`map[string]interface{}`) for destinations: +- `DestinationCreateService.ConfigCustom` and `DestinationCreateService.DoCustom` methods +- `DestinationModifyService.ConfigCustom` and `DestinationModifyService.DoCustom` methods +- `DestinationDetailsService.DoCustom` method ## [0.8.1](https://github.com/fivetran/go-fivetran/compare/v0.8.0...v0.8.1) diff --git a/client.go b/client.go index 931c0f53..752a23c7 100644 --- a/client.go +++ b/client.go @@ -5,20 +5,20 @@ import ( "fmt" "net/http" - "github.com/fivetran/go-fivetran/connectors" "github.com/fivetran/go-fivetran/certificates" + connectcard "github.com/fivetran/go-fivetran/connect_card" + "github.com/fivetran/go-fivetran/connectors" + "github.com/fivetran/go-fivetran/dbt" + "github.com/fivetran/go-fivetran/destinations" + externallogging "github.com/fivetran/go-fivetran/external_logging" "github.com/fivetran/go-fivetran/fingerprints" "github.com/fivetran/go-fivetran/groups" + httputils "github.com/fivetran/go-fivetran/http_utils" + privatelinks "github.com/fivetran/go-fivetran/private_links" + "github.com/fivetran/go-fivetran/roles" + "github.com/fivetran/go-fivetran/teams" "github.com/fivetran/go-fivetran/users" - "github.com/fivetran/go-fivetran/external_logging" - "github.com/fivetran/go-fivetran/destinations" - "github.com/fivetran/go-fivetran/dbt" "github.com/fivetran/go-fivetran/webhooks" - "github.com/fivetran/go-fivetran/teams" - "github.com/fivetran/go-fivetran/roles" - "github.com/fivetran/go-fivetran/connect_card" - "github.com/fivetran/go-fivetran/private_links" - httputils "github.com/fivetran/go-fivetran/http_utils" ) // Client holds client configuration @@ -35,7 +35,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.7.8" +const defaultUserAgent = "Go-Fivetran/0.8.2" // New receives API Key and API Secret, and returns a new Client with the // default HTTP client @@ -523,7 +523,7 @@ func (c *Client) NewRolesList() *roles.RolesListService { } func (c *Client) NewConnectCard() *connectcard.ConnectCardService { - return &connectcard.ConnectCardService{HttpService: c.NewHttpService()} + return &connectcard.ConnectCardService{HttpService: c.NewHttpService()} } /* Connectors */ @@ -550,15 +550,15 @@ func (c *Client) NewConnectorSetupTests() *connectors.ConnectorSetupTestsService } func (c *Client) NewConnectorColumnConfigListService() *connectors.ConnectorColumnConfigListService { - return &connectors.ConnectorColumnConfigListService{HttpService: c.NewHttpService()} + return &connectors.ConnectorColumnConfigListService{HttpService: c.NewHttpService()} } func (c *Client) NewConnectorColumnConfigModifyService() *connectors.ConnectorColumnConfigModifyService { - return &connectors.ConnectorColumnConfigModifyService{HttpService: c.NewHttpService()} + return &connectors.ConnectorColumnConfigModifyService{HttpService: c.NewHttpService()} } func (c *Client) NewConnectorDatabaseSchemaConfigModifyService() *connectors.ConnectorDatabaseSchemaConfigModifyService { - return &connectors.ConnectorDatabaseSchemaConfigModifyService{HttpService: c.NewHttpService()} + return &connectors.ConnectorDatabaseSchemaConfigModifyService{HttpService: c.NewHttpService()} } func (c *Client) NewConnectorReSyncTable() *connectors.ConnectorReSyncTableService { @@ -578,7 +578,7 @@ func (c *Client) NewConnectorSchemaUpdateService() *connectors.ConnectorSchemaCo } func (c *Client) NewConnectorTableConfigModifyService() *connectors.ConnectorTableConfigModifyService { - return &connectors.ConnectorTableConfigModifyService{HttpService: c.NewHttpService()} + return &connectors.ConnectorTableConfigModifyService{HttpService: c.NewHttpService()} } func (c *Client) NewConnectorsSourceMetadata() *connectors.ConnectorsSourceMetadataService { @@ -600,4 +600,4 @@ func (c *Client) NewPrivateLinksDetails() *privatelinks.PrivateLinksDetailsServi func (c *Client) NewPrivateLinksModify() *privatelinks.PrivateLinksModifyService { return &privatelinks.PrivateLinksModifyService{HttpService: c.NewHttpService()} -} \ No newline at end of file +} diff --git a/destinations/common_types.go b/destinations/common_types.go index 1de0ba66..cb391204 100644 --- a/destinations/common_types.go +++ b/destinations/common_types.go @@ -3,27 +3,48 @@ package destinations import "github.com/fivetran/go-fivetran/common" type DestinationDetailsBase struct { - ID string `json:"id"` - GroupID string `json:"group_id"` - Service string `json:"service"` - Region string `json:"region"` - TimeZoneOffset string `json:"time_zone_offset"` - SetupStatus string `json:"setup_status"` - Config DestinationConfigResponse `json:"config"` + ID string `json:"id"` + GroupID string `json:"group_id"` + Service string `json:"service"` + Region string `json:"region"` + TimeZoneOffset string `json:"time_zone_offset"` + SetupStatus string `json:"setup_status"` } type DestinationDetailsWithSetupTestsResponse struct { common.CommonResponse Data struct { DestinationDetailsBase + Config DestinationConfigResponse `json:"config"` + SetupTests []common.SetupTestResponse `json:"setup_tests"` + } `json:"data"` +} + +type DestinationDetailsWithSetupTestsCustomResponse struct { + common.CommonResponse + Data struct { + DestinationDetailsBase + Config map[string]interface{} `json:"config"` SetupTests []common.SetupTestResponse `json:"setup_tests"` } `json:"data"` } type DestinationDetailsResponse struct { - Code string `json:"code"` - Message string `json:"message"` - Data DestinationDetailsBase `json:"data"` + Code string `json:"code"` + Message string `json:"message"` + Data struct { + DestinationDetailsBase + Config DestinationConfigResponse `json:"config"` + } `json:"data"` +} + +type DestinationDetailsCustomResponse struct { + Code string `json:"code"` + Message string `json:"message"` + Data struct { + DestinationDetailsBase + Config map[string]interface{} `json:"config"` + } `json:"data"` } type destinationCreateRequest struct { @@ -49,4 +70,4 @@ type destinationModifyRequest struct { type destinationSetupTestsRequest struct { TrustCertificates *bool `json:"trust_certificates,omitempty"` TrustFingerprints *bool `json:"trust_fingerprints,omitempty"` -} \ No newline at end of file +} diff --git a/destinations/destination_create.go b/destinations/destination_create.go index b5d7c8a1..a47bfc96 100644 --- a/destinations/destination_create.go +++ b/destinations/destination_create.go @@ -15,29 +15,12 @@ type DestinationCreateService struct { region *string timeZoneOffset *string config *DestinationConfig + configCustom *map[string]interface{} trustCertificates *bool trustFingerprints *bool runSetupTests *bool } -func (s *DestinationCreateService) request() *destinationCreateRequest { - var config interface{} - if s.config != nil { - config = s.config.Request() - } - - return &destinationCreateRequest{ - GroupID: s.groupID, - Service: s.service, - Region: s.region, - TimeZoneOffset: s.timeZoneOffset, - Config: config, - TrustCertificates: s.trustCertificates, - TrustFingerprints: s.trustFingerprints, - RunSetupTests: s.runSetupTests, - } -} - func (s *DestinationCreateService) GroupID(value string) *DestinationCreateService { s.groupID = &value return s @@ -63,6 +46,11 @@ func (s *DestinationCreateService) Config(value *DestinationConfig) *Destination return s } +func (s *DestinationCreateService) ConfigCustom(value *map[string]interface{}) *DestinationCreateService { + s.configCustom = value + return s +} + func (s *DestinationCreateService) TrustCertificates(value bool) *DestinationCreateService { s.trustCertificates = &value return s @@ -83,3 +71,40 @@ func (s *DestinationCreateService) Do(ctx context.Context) (DestinationDetailsWi err := s.HttpService.Do(ctx, "POST", "/destinations", s.request(), nil, 201, &response) return response, err } + +func (s *DestinationCreateService) DoCustom(ctx context.Context) (DestinationDetailsWithSetupTestsCustomResponse, error) { + var response DestinationDetailsWithSetupTestsCustomResponse + err := s.HttpService.Do(ctx, "POST", "/destinations", s.requestCustom(), nil, 201, &response) + return response, err +} + +func (s *DestinationCreateService) request() *destinationCreateRequest { + var config interface{} + if s.config != nil { + config = s.config.Request() + } + + return &destinationCreateRequest{ + GroupID: s.groupID, + Service: s.service, + Region: s.region, + TimeZoneOffset: s.timeZoneOffset, + Config: config, + TrustCertificates: s.trustCertificates, + TrustFingerprints: s.trustFingerprints, + RunSetupTests: s.runSetupTests, + } +} + +func (s *DestinationCreateService) requestCustom() *destinationCreateRequest { + return &destinationCreateRequest{ + GroupID: s.groupID, + Service: s.service, + Region: s.region, + TimeZoneOffset: s.timeZoneOffset, + Config: s.configCustom, + TrustCertificates: s.trustCertificates, + TrustFingerprints: s.trustFingerprints, + RunSetupTests: s.runSetupTests, + } +} diff --git a/destinations/destination_create_test.go b/destinations/destination_create_test.go index 7a23e3e7..0122774c 100644 --- a/destinations/destination_create_test.go +++ b/destinations/destination_create_test.go @@ -1,78 +1,78 @@ package destinations_test import ( - "context" - "fmt" - "net/http" - "strconv" - "testing" + "context" + "fmt" + "net/http" + "strconv" + "testing" - "github.com/fivetran/go-fivetran" - "github.com/fivetran/go-fivetran/destinations" - - "github.com/fivetran/go-fivetran/tests/mock" + "github.com/fivetran/go-fivetran" + "github.com/fivetran/go-fivetran/destinations" - testutils "github.com/fivetran/go-fivetran/test_utils" + "github.com/fivetran/go-fivetran/tests/mock" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) const ( - SERVICE = "test_service" - ID = "test_id" - REGION = "GCP_US_EAST4" - TIME_ZONE = "-5" - SETUP_STATUS = "connected" - TEST_TITLE = "Test Title" - TEST_STATUS = "PASSED" - TEST_MESSAGE = "Test message" - HOST = "your.host" - PORT = 443 - DATABASE = "fivetran" - AUTH = "PASSWORD" - USER = "fivetran_user" - MASKED = "******" - CONNECTION_TYPE = "Directly" - TUNNEL_HOST = "tunnel.host" - TUNNEL_PORT = "334" - TUNNEL_USER = "tunnel_user" - PROJECT_ID = "project_id_value" - DATA_SET_LOCATION = "data_Set_location_value" - LOCATION = "data_Set_location_value" - BUCKET = "your-bucket" - SERVER_HOST_NAME = "server.host.name" - HTTP_PATH = "http.path" - CREATE_EXTERNAL_TABLES = true - EXTERNAL_LOCATION = "group_id" - AUTH_TYPE = "auth_type_value" - ROLE_ARN = "role:arn-xxx" - PUBLIC_KEY = "public_key_value" - CLUSTER_ID = "cluster_id_value" - CLUSTER_REGION = "cluster_region_value" - PASSWORD = "password" - PRIVATE_KEY = "private_key" - SECRET_KEY = "secret_key" - TRUST_CERTIFICATES = true - TRUST_FINGERPRINTS = true - RUN_SETUP_TESTS = true - PERSONAL_ACCESS_TOKEN = "PAT" - ROLE = "role" - PASSPHRASE = "passphrase" - IS_PRIVATE_KEY_ENCRYPTED = true - CATALOG = "catalog" - FIVETRAN_ROLE_ARN = "fivetran_role_arn" - PREFIX_PATH = "prefix_path" - STORAGE_ACCOUNT_NAME = "storage_account_name" - CONTAINER_NAME = "container_name" - TENANT_ID = "tenant_id" - CLIENT_ID = "client_id" - SECRET_VALUE = "secret_value" - WORKSPACE_NAME = "workspace_name" - LAKEHOUSE_NAME = "lakehouse_name" + SERVICE = "test_service" + ID = "test_id" + REGION = "GCP_US_EAST4" + TIME_ZONE = "-5" + SETUP_STATUS = "connected" + TEST_TITLE = "Test Title" + TEST_STATUS = "PASSED" + TEST_MESSAGE = "Test message" + HOST = "your.host" + PORT = 443 + DATABASE = "fivetran" + AUTH = "PASSWORD" + USER = "fivetran_user" + MASKED = "******" + CONNECTION_TYPE = "Directly" + TUNNEL_HOST = "tunnel.host" + TUNNEL_PORT = "334" + TUNNEL_USER = "tunnel_user" + PROJECT_ID = "project_id_value" + DATA_SET_LOCATION = "data_Set_location_value" + LOCATION = "data_Set_location_value" + BUCKET = "your-bucket" + SERVER_HOST_NAME = "server.host.name" + HTTP_PATH = "http.path" + CREATE_EXTERNAL_TABLES = true + EXTERNAL_LOCATION = "group_id" + AUTH_TYPE = "auth_type_value" + ROLE_ARN = "role:arn-xxx" + PUBLIC_KEY = "public_key_value" + CLUSTER_ID = "cluster_id_value" + CLUSTER_REGION = "cluster_region_value" + PASSWORD = "password" + PRIVATE_KEY = "private_key" + SECRET_KEY = "secret_key" + TRUST_CERTIFICATES = true + TRUST_FINGERPRINTS = true + RUN_SETUP_TESTS = true + PERSONAL_ACCESS_TOKEN = "PAT" + ROLE = "role" + PASSPHRASE = "passphrase" + IS_PRIVATE_KEY_ENCRYPTED = true + CATALOG = "catalog" + FIVETRAN_ROLE_ARN = "fivetran_role_arn" + PREFIX_PATH = "prefix_path" + STORAGE_ACCOUNT_NAME = "storage_account_name" + CONTAINER_NAME = "container_name" + TENANT_ID = "tenant_id" + CLIENT_ID = "client_id" + SECRET_VALUE = "secret_value" + WORKSPACE_NAME = "workspace_name" + LAKEHOUSE_NAME = "lakehouse_name" ) func TestNewDestinationCreateFullMappingMock(t *testing.T) { - // arrange - ftClient, mockClient := testutils.CreateTestClient() - handler := mockClient.When(http.MethodPost, "/v1/destinations").ThenCall( + // arrange + ftClient, mockClient := testutils.CreateTestClient() + handler := mockClient.When(http.MethodPost, "/v1/destinations").ThenCall( func(req *http.Request) (*http.Response, error) { body := testutils.RequestBodyToJson(t, req) assertRequest(t, body) @@ -80,34 +80,70 @@ func TestNewDestinationCreateFullMappingMock(t *testing.T) { return response, nil }) - // act - response, err := ftClient.NewDestinationCreate(). - Service(SERVICE). - Region(REGION). - TimeZoneOffset(TIME_ZONE). - TrustCertificates(TRUST_CERTIFICATES). - TrustFingerprints(TRUST_FINGERPRINTS). - RunSetupTests(RUN_SETUP_TESTS). - GroupID(ID). - Config(prepareConfig()). - Do(context.Background()) + // act + response, err := ftClient.NewDestinationCreate(). + Service(SERVICE). + Region(REGION). + TimeZoneOffset(TIME_ZONE). + TrustCertificates(TRUST_CERTIFICATES). + TrustFingerprints(TRUST_FINGERPRINTS). + RunSetupTests(RUN_SETUP_TESTS). + GroupID(ID). + Config(prepareConfig()). + Do(context.Background()) - if err != nil { - t.Logf("%+v\n", response) - t.Error(err) - } + if err != nil { + t.Logf("%+v\n", response) + t.Error(err) + } - // testutils.Assert - interactions := mockClient.Interactions() - testutils.AssertEqual(t, len(interactions), 1) - testutils.AssertEqual(t, interactions[0].Handler, handler) - testutils.AssertEqual(t, handler.Interactions, 1) - assertResponse(t, response) + // testutils.Assert + interactions := mockClient.Interactions() + testutils.AssertEqual(t, len(interactions), 1) + testutils.AssertEqual(t, interactions[0].Handler, handler) + testutils.AssertEqual(t, handler.Interactions, 1) + assertResponse(t, response) +} + +func TestNewDestinationCreateCustomFullMappingMock(t *testing.T) { + // arrange + ftClient, mockClient := testutils.CreateTestClient() + handler := mockClient.When(http.MethodPost, "/v1/destinations").ThenCall( + func(req *http.Request) (*http.Response, error) { + body := testutils.RequestBodyToJson(t, req) + assertRequest(t, body) + response := mock.NewResponse(req, http.StatusCreated, prepareDestinationResponse()) + return response, nil + }) + + // act + response, err := ftClient.NewDestinationCreate(). + Service(SERVICE). + Region(REGION). + TimeZoneOffset(TIME_ZONE). + TrustCertificates(TRUST_CERTIFICATES). + TrustFingerprints(TRUST_FINGERPRINTS). + RunSetupTests(RUN_SETUP_TESTS). + GroupID(ID). + ConfigCustom(prepareConfigCustom()). + DoCustom(context.Background()) + + if err != nil { + t.Logf("%+v\n", response) + t.Error(err) + } + + // testutils.Assert + interactions := mockClient.Interactions() + testutils.AssertEqual(t, len(interactions), 1) + testutils.AssertEqual(t, interactions[0].Handler, handler) + testutils.AssertEqual(t, handler.Interactions, 1) + asserResponseCustom(t, response) } func prepareDestinationResponse() string { - return fmt.Sprintf( - `{ + return fmt.Sprintf( + `{ "code":"Created", "message":"Destination has been created", "data":{ @@ -168,209 +204,309 @@ func prepareDestinationResponse() string { } } }`, - ID, // id - ID, // group_id - SERVICE, - REGION, - TIME_ZONE, // time_zone_offset - SETUP_STATUS, - TEST_TITLE, - TEST_STATUS, - TEST_MESSAGE, - HOST, - PORT, - DATABASE, - AUTH, - USER, - MASKED, // password - CONNECTION_TYPE, - TUNNEL_HOST, - TUNNEL_PORT, - TUNNEL_USER, - PROJECT_ID, - DATA_SET_LOCATION, - LOCATION, - BUCKET, - SERVER_HOST_NAME, - HTTP_PATH, - MASKED, // personal_access_token - CREATE_EXTERNAL_TABLES, - EXTERNAL_LOCATION, - AUTH_TYPE, - ROLE_ARN, - MASKED, // secret_key - MASKED, // private_key - PUBLIC_KEY, - CLUSTER_ID, - CLUSTER_REGION, - ROLE, - IS_PRIVATE_KEY_ENCRYPTED, - PASSPHRASE, - CATALOG, - FIVETRAN_ROLE_ARN, - PREFIX_PATH, - REGION, - STORAGE_ACCOUNT_NAME, - CONTAINER_NAME, - TENANT_ID, - CLIENT_ID, - SECRET_VALUE, - WORKSPACE_NAME, - LAKEHOUSE_NAME, - ) + ID, // id + ID, // group_id + SERVICE, + REGION, + TIME_ZONE, // time_zone_offset + SETUP_STATUS, + TEST_TITLE, + TEST_STATUS, + TEST_MESSAGE, + HOST, + PORT, + DATABASE, + AUTH, + USER, + MASKED, // password + CONNECTION_TYPE, + TUNNEL_HOST, + TUNNEL_PORT, + TUNNEL_USER, + PROJECT_ID, + DATA_SET_LOCATION, + LOCATION, + BUCKET, + SERVER_HOST_NAME, + HTTP_PATH, + MASKED, // personal_access_token + CREATE_EXTERNAL_TABLES, + EXTERNAL_LOCATION, + AUTH_TYPE, + ROLE_ARN, + MASKED, // secret_key + MASKED, // private_key + PUBLIC_KEY, + CLUSTER_ID, + CLUSTER_REGION, + ROLE, + IS_PRIVATE_KEY_ENCRYPTED, + PASSPHRASE, + CATALOG, + FIVETRAN_ROLE_ARN, + PREFIX_PATH, + REGION, + STORAGE_ACCOUNT_NAME, + CONTAINER_NAME, + TENANT_ID, + CLIENT_ID, + SECRET_VALUE, + WORKSPACE_NAME, + LAKEHOUSE_NAME, + ) +} + +func prepareConfigCustom() *map[string]interface{} { + return &(map[string]interface{}{ + "host": HOST, + "port": PORT, + "database": DATABASE, + "auth": AUTH, + "user": USER, + "password": PASSWORD, + "connection_type": CONNECTION_TYPE, + "tunnel_host": TUNNEL_HOST, + "tunnel_port": TUNNEL_PORT, + "tunnel_user": TUNNEL_USER, + "project_id": PROJECT_ID, + "bucket": BUCKET, + "server_host_name": SERVER_HOST_NAME, + "http_path": HTTP_PATH, + "personal_access_token": PERSONAL_ACCESS_TOKEN, + "create_external_tables": CREATE_EXTERNAL_TABLES, + "external_location": EXTERNAL_LOCATION, + "auth_type": AUTH_TYPE, + "role_arn": ROLE_ARN, + "secret_key": SECRET_KEY, + "private_key": PRIVATE_KEY, + "cluster_id": CLUSTER_ID, + "cluster_region": CLUSTER_REGION, + "role": ROLE, + "is_private_key_encrypted": IS_PRIVATE_KEY_ENCRYPTED, + "passphrase": PASSPHRASE, + "catalog": CATALOG, + "fivetran_role_arn": FIVETRAN_ROLE_ARN, + "region": REGION, + "prefix_path": PREFIX_PATH, + "storage_account_name": STORAGE_ACCOUNT_NAME, + "container_name": CONTAINER_NAME, + "tenant_id": TENANT_ID, + "client_id": CLIENT_ID, + "secret_value": SECRET_VALUE, + "workspace_name": WORKSPACE_NAME, + "lakehouse_name": LAKEHOUSE_NAME, + }) } func prepareConfig() *destinations.DestinationConfig { - config := fivetran.NewDestinationConfig() - config.Host(HOST) - config.Port(PORT) - config.Database(DATABASE) - config.Auth(AUTH) - config.User(USER) - config.Password(PASSWORD) - config.ConnectionType(CONNECTION_TYPE) - config.TunnelHost(TUNNEL_HOST) - config.TunnelPort(TUNNEL_PORT) - config.TunnelUser(TUNNEL_USER) - config.ProjectID(PROJECT_ID) - config.Bucket(BUCKET) - config.ServerHostName(SERVER_HOST_NAME) - config.HTTPPath(HTTP_PATH) - config.PersonalAccessToken(PERSONAL_ACCESS_TOKEN) - config.CreateExternalTables(CREATE_EXTERNAL_TABLES) - config.ExternalLocation(EXTERNAL_LOCATION) - config.AuthType(AUTH_TYPE) - config.RoleArn(ROLE_ARN) - config.SecretKey(SECRET_KEY) - config.PrivateKey(PRIVATE_KEY) - config.ClusterId(CLUSTER_ID) - config.ClusterRegion(CLUSTER_REGION) - config.Role(ROLE) - config.IsPrivateKeyEncrypted(IS_PRIVATE_KEY_ENCRYPTED) - config.Passphrase(PASSPHRASE) - config.Catalog(CATALOG) - config.FivetranRoleArn(FIVETRAN_ROLE_ARN) - config.PrefixPath(PREFIX_PATH) - config.Region(REGION) - config.StorageAccountName(STORAGE_ACCOUNT_NAME) - config.ContainerName(CONTAINER_NAME) - config.TenantId(TENANT_ID) - config.ClientId(CLIENT_ID) - config.SecretValue(SECRET_VALUE) - config.WorkspaceName(WORKSPACE_NAME) - config.LakehouseName(LAKEHOUSE_NAME) + config := fivetran.NewDestinationConfig() + config.Host(HOST) + config.Port(PORT) + config.Database(DATABASE) + config.Auth(AUTH) + config.User(USER) + config.Password(PASSWORD) + config.ConnectionType(CONNECTION_TYPE) + config.TunnelHost(TUNNEL_HOST) + config.TunnelPort(TUNNEL_PORT) + config.TunnelUser(TUNNEL_USER) + config.ProjectID(PROJECT_ID) + config.Bucket(BUCKET) + config.ServerHostName(SERVER_HOST_NAME) + config.HTTPPath(HTTP_PATH) + config.PersonalAccessToken(PERSONAL_ACCESS_TOKEN) + config.CreateExternalTables(CREATE_EXTERNAL_TABLES) + config.ExternalLocation(EXTERNAL_LOCATION) + config.AuthType(AUTH_TYPE) + config.RoleArn(ROLE_ARN) + config.SecretKey(SECRET_KEY) + config.PrivateKey(PRIVATE_KEY) + config.ClusterId(CLUSTER_ID) + config.ClusterRegion(CLUSTER_REGION) + config.Role(ROLE) + config.IsPrivateKeyEncrypted(IS_PRIVATE_KEY_ENCRYPTED) + config.Passphrase(PASSPHRASE) + config.Catalog(CATALOG) + config.FivetranRoleArn(FIVETRAN_ROLE_ARN) + config.PrefixPath(PREFIX_PATH) + config.Region(REGION) + config.StorageAccountName(STORAGE_ACCOUNT_NAME) + config.ContainerName(CONTAINER_NAME) + config.TenantId(TENANT_ID) + config.ClientId(CLIENT_ID) + config.SecretValue(SECRET_VALUE) + config.WorkspaceName(WORKSPACE_NAME) + config.LakehouseName(LAKEHOUSE_NAME) - return config + return config } func assertRequest(t *testing.T, request map[string]interface{}) { - testutils.AssertKey(t, "service", request, SERVICE) - testutils.AssertKey(t, "region", request, REGION) - testutils.AssertKey(t, "time_zone_offset", request, TIME_ZONE) - testutils.AssertKey(t, "trust_certificates", request, TRUST_CERTIFICATES) - testutils.AssertKey(t, "trust_fingerprints", request, TRUST_FINGERPRINTS) - testutils.AssertKey(t, "run_setup_tests", request, RUN_SETUP_TESTS) - testutils.AssertKey(t, "group_id", request, ID) + testutils.AssertKey(t, "service", request, SERVICE) + testutils.AssertKey(t, "region", request, REGION) + testutils.AssertKey(t, "time_zone_offset", request, TIME_ZONE) + testutils.AssertKey(t, "trust_certificates", request, TRUST_CERTIFICATES) + testutils.AssertKey(t, "trust_fingerprints", request, TRUST_FINGERPRINTS) + testutils.AssertKey(t, "run_setup_tests", request, RUN_SETUP_TESTS) + testutils.AssertKey(t, "group_id", request, ID) + + c, ok := request["config"] + testutils.AssertEqual(t, ok, true) + config, ok := c.(map[string]interface{}) + testutils.AssertEqual(t, ok, true) + + testutils.AssertKey(t, "host", config, HOST) + testutils.AssertKey(t, "port", config, float64(PORT)) // json marshalling stores all numbers as float64 + testutils.AssertKey(t, "database", config, DATABASE) + testutils.AssertKey(t, "auth", config, AUTH) + testutils.AssertKey(t, "user", config, USER) + testutils.AssertKey(t, "password", config, PASSWORD) + testutils.AssertKey(t, "connection_type", config, CONNECTION_TYPE) + testutils.AssertKey(t, "tunnel_host", config, TUNNEL_HOST) + testutils.AssertKey(t, "tunnel_port", config, TUNNEL_PORT) + testutils.AssertKey(t, "tunnel_user", config, TUNNEL_USER) + testutils.AssertKey(t, "project_id", config, PROJECT_ID) + testutils.AssertKey(t, "bucket", config, BUCKET) + testutils.AssertKey(t, "server_host_name", config, SERVER_HOST_NAME) + testutils.AssertKey(t, "http_path", config, HTTP_PATH) + testutils.AssertKey(t, "personal_access_token", config, PERSONAL_ACCESS_TOKEN) + testutils.AssertKey(t, "create_external_tables", config, CREATE_EXTERNAL_TABLES) + testutils.AssertKey(t, "external_location", config, EXTERNAL_LOCATION) + testutils.AssertKey(t, "auth_type", config, AUTH_TYPE) + testutils.AssertKey(t, "role_arn", config, ROLE_ARN) + testutils.AssertKey(t, "secret_key", config, SECRET_KEY) + testutils.AssertKey(t, "private_key", config, PRIVATE_KEY) + testutils.AssertKey(t, "cluster_id", config, CLUSTER_ID) + testutils.AssertKey(t, "cluster_region", config, CLUSTER_REGION) + testutils.AssertKey(t, "role", config, ROLE) + testutils.AssertKey(t, "is_private_key_encrypted", config, IS_PRIVATE_KEY_ENCRYPTED) + testutils.AssertKey(t, "passphrase", config, PASSPHRASE) + testutils.AssertKey(t, "catalog", config, CATALOG) + testutils.AssertKey(t, "fivetran_role_arn", config, FIVETRAN_ROLE_ARN) + testutils.AssertKey(t, "prefix_path", config, PREFIX_PATH) + testutils.AssertKey(t, "region", config, REGION) + testutils.AssertKey(t, "storage_account_name", config, STORAGE_ACCOUNT_NAME) + testutils.AssertKey(t, "container_name", config, CONTAINER_NAME) + testutils.AssertKey(t, "tenant_id", config, TENANT_ID) + testutils.AssertKey(t, "client_id", config, CLIENT_ID) + testutils.AssertKey(t, "secret_value", config, SECRET_VALUE) + testutils.AssertKey(t, "workspace_name", config, WORKSPACE_NAME) + testutils.AssertKey(t, "lakehouse_name", config, LAKEHOUSE_NAME) +} + +func asserResponseCustom(t *testing.T, response destinations.DestinationDetailsWithSetupTestsCustomResponse) { + testutils.AssertEqual(t, response.Code, "Created") + testutils.AssertNotEmpty(t, response.Message) + + testutils.AssertEqual(t, response.Data.GroupID, ID) + testutils.AssertEqual(t, response.Data.ID, ID) + testutils.AssertEqual(t, response.Data.Region, REGION) + testutils.AssertEqual(t, response.Data.Service, SERVICE) + testutils.AssertEqual(t, response.Data.SetupStatus, SETUP_STATUS) + testutils.AssertEqual(t, response.Data.TimeZoneOffset, TIME_ZONE) - c, ok := request["config"] - testutils.AssertEqual(t, ok, true) - config, ok := c.(map[string]interface{}) - testutils.AssertEqual(t, ok, true) + testutils.AssertEqual(t, len(response.Data.SetupTests), 1) + testutils.AssertEqual(t, response.Data.SetupTests[0].Message, TEST_MESSAGE) + testutils.AssertEqual(t, response.Data.SetupTests[0].Status, TEST_STATUS) + testutils.AssertEqual(t, response.Data.SetupTests[0].Title, TEST_TITLE) - testutils.AssertKey(t, "host", config, HOST) - testutils.AssertKey(t, "port", config, float64(PORT)) // json marshalling stores all numbers as float64 - testutils.AssertKey(t, "database", config, DATABASE) - testutils.AssertKey(t, "auth", config, AUTH) - testutils.AssertKey(t, "user", config, USER) - testutils.AssertKey(t, "password", config, PASSWORD) - testutils.AssertKey(t, "connection_type", config, CONNECTION_TYPE) - testutils.AssertKey(t, "tunnel_host", config, TUNNEL_HOST) - testutils.AssertKey(t, "tunnel_port", config, TUNNEL_PORT) - testutils.AssertKey(t, "tunnel_user", config, TUNNEL_USER) - testutils.AssertKey(t, "project_id", config, PROJECT_ID) - testutils.AssertKey(t, "bucket", config, BUCKET) - testutils.AssertKey(t, "server_host_name", config, SERVER_HOST_NAME) - testutils.AssertKey(t, "http_path", config, HTTP_PATH) - testutils.AssertKey(t, "personal_access_token", config, PERSONAL_ACCESS_TOKEN) - testutils.AssertKey(t, "create_external_tables", config, CREATE_EXTERNAL_TABLES) - testutils.AssertKey(t, "external_location", config, EXTERNAL_LOCATION) - testutils.AssertKey(t, "auth_type", config, AUTH_TYPE) - testutils.AssertKey(t, "role_arn", config, ROLE_ARN) - testutils.AssertKey(t, "secret_key", config, SECRET_KEY) - testutils.AssertKey(t, "private_key", config, PRIVATE_KEY) - testutils.AssertKey(t, "cluster_id", config, CLUSTER_ID) - testutils.AssertKey(t, "cluster_region", config, CLUSTER_REGION) - testutils.AssertKey(t, "role", config, ROLE) - testutils.AssertKey(t, "is_private_key_encrypted", config, IS_PRIVATE_KEY_ENCRYPTED) - testutils.AssertKey(t, "passphrase", config, PASSPHRASE) - testutils.AssertKey(t, "catalog", config, CATALOG) - testutils.AssertKey(t, "fivetran_role_arn", config, FIVETRAN_ROLE_ARN) - testutils.AssertKey(t, "prefix_path", config, PREFIX_PATH) - testutils.AssertKey(t, "region", config, REGION) - testutils.AssertKey(t, "storage_account_name", config, STORAGE_ACCOUNT_NAME) - testutils.AssertKey(t, "container_name", config, CONTAINER_NAME) - testutils.AssertKey(t, "tenant_id", config, TENANT_ID) - testutils.AssertKey(t, "client_id", config, CLIENT_ID) - testutils.AssertKey(t, "secret_value", config, SECRET_VALUE) - testutils.AssertKey(t, "workspace_name", config, WORKSPACE_NAME) - testutils.AssertKey(t, "lakehouse_name", config, LAKEHOUSE_NAME) + testutils.AssertEqual(t, response.Data.Config["auth"], AUTH) + testutils.AssertEqual(t, response.Data.Config["auth_type"], AUTH_TYPE) + testutils.AssertEqual(t, response.Data.Config["bucket"], BUCKET) + testutils.AssertEqual(t, response.Data.Config["cluster_id"], CLUSTER_ID) + testutils.AssertEqual(t, response.Data.Config["cluster_region"], CLUSTER_REGION) + testutils.AssertEqual(t, response.Data.Config["connection_type"], CONNECTION_TYPE) + testutils.AssertEqual(t, response.Data.Config["create_external_tables"], testutils.BoolToStr(CREATE_EXTERNAL_TABLES)) // Inconsistent response + testutils.AssertEqual(t, response.Data.Config["data_set_location"], DATA_SET_LOCATION) + testutils.AssertEqual(t, response.Data.Config["database"], DATABASE) + testutils.AssertEqual(t, response.Data.Config["external_location"], EXTERNAL_LOCATION) + testutils.AssertEqual(t, response.Data.Config["http_path"], HTTP_PATH) + testutils.AssertEqual(t, response.Data.Config["host"], HOST) + testutils.AssertEqual(t, response.Data.Config["password"], MASKED) + testutils.AssertEqual(t, response.Data.Config["personal_access_token"], MASKED) + testutils.AssertEqual(t, response.Data.Config["port"], strconv.Itoa(PORT)) + testutils.AssertEqual(t, response.Data.Config["private_key"], MASKED) + testutils.AssertEqual(t, response.Data.Config["project_id"], PROJECT_ID) + testutils.AssertEqual(t, response.Data.Config["public_key"], PUBLIC_KEY) + testutils.AssertEqual(t, response.Data.Config["role_arn"], ROLE_ARN) + testutils.AssertEqual(t, response.Data.Config["secret_key"], MASKED) + testutils.AssertEqual(t, response.Data.Config["server_host_name"], SERVER_HOST_NAME) + testutils.AssertEqual(t, response.Data.Config["tunnel_host"], TUNNEL_HOST) + testutils.AssertEqual(t, response.Data.Config["tunnel_port"], TUNNEL_PORT) + testutils.AssertEqual(t, response.Data.Config["tunnel_user"], TUNNEL_USER) + testutils.AssertEqual(t, response.Data.Config["user"], USER) + testutils.AssertEqual(t, response.Data.Config["location"], LOCATION) + testutils.AssertEqual(t, response.Data.Config["role"], ROLE) + testutils.AssertEqual(t, response.Data.Config["is_private_key_encrypted"], testutils.BoolToStr(IS_PRIVATE_KEY_ENCRYPTED)) + testutils.AssertEqual(t, response.Data.Config["passphrase"], PASSPHRASE) + testutils.AssertEqual(t, response.Data.Config["catalog"], CATALOG) + testutils.AssertEqual(t, response.Data.Config["fivetran_role_arn"], FIVETRAN_ROLE_ARN) + testutils.AssertEqual(t, response.Data.Config["prefix_path"], PREFIX_PATH) + testutils.AssertEqual(t, response.Data.Config["region"], REGION) + testutils.AssertEqual(t, response.Data.Config["storage_account_name"], STORAGE_ACCOUNT_NAME) + testutils.AssertEqual(t, response.Data.Config["container_name"], CONTAINER_NAME) + testutils.AssertEqual(t, response.Data.Config["tenant_id"], TENANT_ID) + testutils.AssertEqual(t, response.Data.Config["client_id"], CLIENT_ID) + testutils.AssertEqual(t, response.Data.Config["secret_value"], SECRET_VALUE) + testutils.AssertEqual(t, response.Data.Config["workspace_name"], WORKSPACE_NAME) + testutils.AssertEqual(t, response.Data.Config["lakehouse_name"], LAKEHOUSE_NAME) } func assertResponse(t *testing.T, response destinations.DestinationDetailsWithSetupTestsResponse) { - testutils.AssertEqual(t, response.Code, "Created") - testutils.AssertNotEmpty(t, response.Message) + testutils.AssertEqual(t, response.Code, "Created") + testutils.AssertNotEmpty(t, response.Message) - testutils.AssertEqual(t, response.Data.GroupID, ID) - testutils.AssertEqual(t, response.Data.ID, ID) - testutils.AssertEqual(t, response.Data.Region, REGION) - testutils.AssertEqual(t, response.Data.Service, SERVICE) - testutils.AssertEqual(t, response.Data.SetupStatus, SETUP_STATUS) - testutils.AssertEqual(t, response.Data.TimeZoneOffset, TIME_ZONE) + testutils.AssertEqual(t, response.Data.GroupID, ID) + testutils.AssertEqual(t, response.Data.ID, ID) + testutils.AssertEqual(t, response.Data.Region, REGION) + testutils.AssertEqual(t, response.Data.Service, SERVICE) + testutils.AssertEqual(t, response.Data.SetupStatus, SETUP_STATUS) + testutils.AssertEqual(t, response.Data.TimeZoneOffset, TIME_ZONE) - testutils.AssertEqual(t, len(response.Data.SetupTests), 1) - testutils.AssertEqual(t, response.Data.SetupTests[0].Message, TEST_MESSAGE) - testutils.AssertEqual(t, response.Data.SetupTests[0].Status, TEST_STATUS) - testutils.AssertEqual(t, response.Data.SetupTests[0].Title, TEST_TITLE) + testutils.AssertEqual(t, len(response.Data.SetupTests), 1) + testutils.AssertEqual(t, response.Data.SetupTests[0].Message, TEST_MESSAGE) + testutils.AssertEqual(t, response.Data.SetupTests[0].Status, TEST_STATUS) + testutils.AssertEqual(t, response.Data.SetupTests[0].Title, TEST_TITLE) - testutils.AssertEqual(t, response.Data.Config.Auth, AUTH) - testutils.AssertEqual(t, response.Data.Config.AuthType, AUTH_TYPE) - testutils.AssertEqual(t, response.Data.Config.Bucket, BUCKET) - testutils.AssertEqual(t, response.Data.Config.ClusterId, CLUSTER_ID) - testutils.AssertEqual(t, response.Data.Config.ClusterRegion, CLUSTER_REGION) - testutils.AssertEqual(t, response.Data.Config.ConnectionType, CONNECTION_TYPE) - testutils.AssertEqual(t, response.Data.Config.CreateExternalTables, testutils.BoolToStr(CREATE_EXTERNAL_TABLES)) // Inconsistent response - testutils.AssertEqual(t, response.Data.Config.DataSetLocation, DATA_SET_LOCATION) - testutils.AssertEqual(t, response.Data.Config.Database, DATABASE) - testutils.AssertEqual(t, response.Data.Config.ExternalLocation, EXTERNAL_LOCATION) - testutils.AssertEqual(t, response.Data.Config.HTTPPath, HTTP_PATH) - testutils.AssertEqual(t, response.Data.Config.Host, HOST) - testutils.AssertEqual(t, response.Data.Config.Password, MASKED) - testutils.AssertEqual(t, response.Data.Config.PersonalAccessToken, MASKED) - testutils.AssertEqual(t, response.Data.Config.Port, strconv.Itoa(PORT)) - testutils.AssertEqual(t, response.Data.Config.PrivateKey, MASKED) - testutils.AssertEqual(t, response.Data.Config.ProjectID, PROJECT_ID) - testutils.AssertEqual(t, response.Data.Config.PublicKey, PUBLIC_KEY) - testutils.AssertEqual(t, response.Data.Config.RoleArn, ROLE_ARN) - testutils.AssertEqual(t, response.Data.Config.SecretKey, MASKED) - testutils.AssertEqual(t, response.Data.Config.ServerHostName, SERVER_HOST_NAME) - testutils.AssertEqual(t, response.Data.Config.TunnelHost, TUNNEL_HOST) - testutils.AssertEqual(t, response.Data.Config.TunnelPort, TUNNEL_PORT) - testutils.AssertEqual(t, response.Data.Config.TunnelUser, TUNNEL_USER) - testutils.AssertEqual(t, response.Data.Config.User, USER) - testutils.AssertEqual(t, response.Data.Config.Location, LOCATION) - testutils.AssertEqual(t, response.Data.Config.Role, ROLE) - testutils.AssertEqual(t, response.Data.Config.IsPrivateKeyEncrypted, testutils.BoolToStr(IS_PRIVATE_KEY_ENCRYPTED)) - testutils.AssertEqual(t, response.Data.Config.Passphrase, PASSPHRASE) - testutils.AssertEqual(t, response.Data.Config.Catalog, CATALOG) - testutils.AssertEqual(t, response.Data.Config.FivetranRoleArn, FIVETRAN_ROLE_ARN) - testutils.AssertEqual(t, response.Data.Config.PrefixPath, PREFIX_PATH) - testutils.AssertEqual(t, response.Data.Config.Region, REGION) - testutils.AssertEqual(t, response.Data.Config.StorageAccountName, STORAGE_ACCOUNT_NAME) - testutils.AssertEqual(t, response.Data.Config.ContainerName, CONTAINER_NAME) - testutils.AssertEqual(t, response.Data.Config.TenantId, TENANT_ID) - testutils.AssertEqual(t, response.Data.Config.ClientId, CLIENT_ID) - testutils.AssertEqual(t, response.Data.Config.SecretValue, SECRET_VALUE) - testutils.AssertEqual(t, response.Data.Config.WorkspaceName, WORKSPACE_NAME) - testutils.AssertEqual(t, response.Data.Config.LakehouseName, LAKEHOUSE_NAME) + testutils.AssertEqual(t, response.Data.Config.Auth, AUTH) + testutils.AssertEqual(t, response.Data.Config.AuthType, AUTH_TYPE) + testutils.AssertEqual(t, response.Data.Config.Bucket, BUCKET) + testutils.AssertEqual(t, response.Data.Config.ClusterId, CLUSTER_ID) + testutils.AssertEqual(t, response.Data.Config.ClusterRegion, CLUSTER_REGION) + testutils.AssertEqual(t, response.Data.Config.ConnectionType, CONNECTION_TYPE) + testutils.AssertEqual(t, response.Data.Config.CreateExternalTables, testutils.BoolToStr(CREATE_EXTERNAL_TABLES)) // Inconsistent response + testutils.AssertEqual(t, response.Data.Config.DataSetLocation, DATA_SET_LOCATION) + testutils.AssertEqual(t, response.Data.Config.Database, DATABASE) + testutils.AssertEqual(t, response.Data.Config.ExternalLocation, EXTERNAL_LOCATION) + testutils.AssertEqual(t, response.Data.Config.HTTPPath, HTTP_PATH) + testutils.AssertEqual(t, response.Data.Config.Host, HOST) + testutils.AssertEqual(t, response.Data.Config.Password, MASKED) + testutils.AssertEqual(t, response.Data.Config.PersonalAccessToken, MASKED) + testutils.AssertEqual(t, response.Data.Config.Port, strconv.Itoa(PORT)) + testutils.AssertEqual(t, response.Data.Config.PrivateKey, MASKED) + testutils.AssertEqual(t, response.Data.Config.ProjectID, PROJECT_ID) + testutils.AssertEqual(t, response.Data.Config.PublicKey, PUBLIC_KEY) + testutils.AssertEqual(t, response.Data.Config.RoleArn, ROLE_ARN) + testutils.AssertEqual(t, response.Data.Config.SecretKey, MASKED) + testutils.AssertEqual(t, response.Data.Config.ServerHostName, SERVER_HOST_NAME) + testutils.AssertEqual(t, response.Data.Config.TunnelHost, TUNNEL_HOST) + testutils.AssertEqual(t, response.Data.Config.TunnelPort, TUNNEL_PORT) + testutils.AssertEqual(t, response.Data.Config.TunnelUser, TUNNEL_USER) + testutils.AssertEqual(t, response.Data.Config.User, USER) + testutils.AssertEqual(t, response.Data.Config.Location, LOCATION) + testutils.AssertEqual(t, response.Data.Config.Role, ROLE) + testutils.AssertEqual(t, response.Data.Config.IsPrivateKeyEncrypted, testutils.BoolToStr(IS_PRIVATE_KEY_ENCRYPTED)) + testutils.AssertEqual(t, response.Data.Config.Passphrase, PASSPHRASE) + testutils.AssertEqual(t, response.Data.Config.Catalog, CATALOG) + testutils.AssertEqual(t, response.Data.Config.FivetranRoleArn, FIVETRAN_ROLE_ARN) + testutils.AssertEqual(t, response.Data.Config.PrefixPath, PREFIX_PATH) + testutils.AssertEqual(t, response.Data.Config.Region, REGION) + testutils.AssertEqual(t, response.Data.Config.StorageAccountName, STORAGE_ACCOUNT_NAME) + testutils.AssertEqual(t, response.Data.Config.ContainerName, CONTAINER_NAME) + testutils.AssertEqual(t, response.Data.Config.TenantId, TENANT_ID) + testutils.AssertEqual(t, response.Data.Config.ClientId, CLIENT_ID) + testutils.AssertEqual(t, response.Data.Config.SecretValue, SECRET_VALUE) + testutils.AssertEqual(t, response.Data.Config.WorkspaceName, WORKSPACE_NAME) + testutils.AssertEqual(t, response.Data.Config.LakehouseName, LAKEHOUSE_NAME) } diff --git a/destinations/destination_details.go b/destinations/destination_details.go index 4cfbd373..9b01bc38 100644 --- a/destinations/destination_details.go +++ b/destinations/destination_details.go @@ -30,3 +30,15 @@ func (s *DestinationDetailsService) Do(ctx context.Context) (DestinationDetailsR err := s.HttpService.Do(ctx, "GET", url, nil, nil, 200, &response) return response, err } + +func (s *DestinationDetailsService) DoCustom(ctx context.Context) (DestinationDetailsCustomResponse, error) { + var response DestinationDetailsCustomResponse + + if s.destinationID == nil { + return response, fmt.Errorf("missing required destinationID") + } + + url := fmt.Sprintf("/destinations/%v", *s.destinationID) + err := s.HttpService.Do(ctx, "GET", url, nil, nil, 200, &response) + return response, err +} diff --git a/destinations/destination_details_test.go b/destinations/destination_details_test.go index 65aa56e0..800b974b 100644 --- a/destinations/destination_details_test.go +++ b/destinations/destination_details_test.go @@ -1,16 +1,16 @@ package destinations_test import ( - "context" - "fmt" - "net/http" - "testing" + "context" + "fmt" + "net/http" + "testing" - "github.com/fivetran/go-fivetran/destinations" - - "github.com/fivetran/go-fivetran/tests/mock" + "github.com/fivetran/go-fivetran/destinations" - testutils "github.com/fivetran/go-fivetran/test_utils" + "github.com/fivetran/go-fivetran/tests/mock" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) const DESTINATION_DETAILS_SERVICE = "snowflake" @@ -53,6 +53,34 @@ func TestDestinationDetailsService(t *testing.T) { assertDestinationDetailsResponse(t, response) } +func TestDestinationDetailsCustomService(t *testing.T) { + // arrange + ftClient, mockClient := testutils.CreateTestClient() + handler := mockClient.When(http.MethodGet, "/v1/destinations/"+ID).ThenCall( + func(req *http.Request) (*http.Response, error) { + response := mock.NewResponse(req, http.StatusOK, prepareDestinationDetailsResponse()) + return response, nil + }) + + service := ftClient.NewDestinationDetails().DestinationID(ID) + + // act + response, err := service.DoCustom(context.Background()) + + if err != nil { + t.Logf("%+v\n", response) + t.Error(err) + } + + // assert + interactions := mockClient.Interactions() + testutils.AssertEqual(t, len(interactions), 1) + testutils.AssertEqual(t, interactions[0].Handler, handler) + testutils.AssertEqual(t, handler.Interactions, 1) + + assertDestinationDetailsCustomResponse(t, response) +} + func prepareDestinationDetailsResponse() string { return fmt.Sprintf(`{ "code": "Success", @@ -102,3 +130,19 @@ func assertDestinationDetailsResponse(t *testing.T, response destinations.Destin testutils.AssertEqual(t, response.Data.Config.User, DESTINATION_DETAILS_USER) testutils.AssertEqual(t, response.Data.Config.Password, DESTINATION_DETAILS_MASKED_PASSWORD) } + +func assertDestinationDetailsCustomResponse(t *testing.T, response destinations.DestinationDetailsCustomResponse) { + testutils.AssertEqual(t, response.Code, "Success") + testutils.AssertEqual(t, response.Data.ID, DESTINATION_DETAILS_ID) + testutils.AssertEqual(t, response.Data.GroupID, DESTINATION_DETAILS_ID) + testutils.AssertEqual(t, response.Data.Service, DESTINATION_DETAILS_SERVICE) + testutils.AssertEqual(t, response.Data.Region, DESTINATION_DETAILS_REGION) + testutils.AssertEqual(t, response.Data.TimeZoneOffset, DESTINATION_DETAILS_TIME_ZONE) + testutils.AssertEqual(t, response.Data.SetupStatus, DESTINATION_DETAILS_SETUP_STATUS) + testutils.AssertEqual(t, response.Data.Config["host"], DESTINATION_DETAILS_HOST) + testutils.AssertEqual(t, response.Data.Config["port"], DESTINATION_DETAILS_PORT) + testutils.AssertEqual(t, response.Data.Config["database"], DESTINATION_DETAILS_DATABASE) + testutils.AssertEqual(t, response.Data.Config["auth"], DESTINATION_DETAILS_AUTH) + testutils.AssertEqual(t, response.Data.Config["user"], DESTINATION_DETAILS_USER) + testutils.AssertEqual(t, response.Data.Config["password"], DESTINATION_DETAILS_MASKED_PASSWORD) +} diff --git a/destinations/destination_modify.go b/destinations/destination_modify.go index aaceed44..1dec4ebb 100644 --- a/destinations/destination_modify.go +++ b/destinations/destination_modify.go @@ -15,6 +15,7 @@ type DestinationModifyService struct { region *string timeZoneOffset *string config *DestinationConfig + configCustom *map[string]interface{} trustCertificates *bool trustFingerprints *bool runSetupTests *bool @@ -37,6 +38,17 @@ func (s *DestinationModifyService) request() *destinationModifyRequest { } } +func (s *DestinationModifyService) requestCustom() *destinationModifyRequest { + return &destinationModifyRequest{ + Region: s.region, + TimeZoneOffset: s.timeZoneOffset, + Config: s.configCustom, + TrustCertificates: s.trustCertificates, + TrustFingerprints: s.trustFingerprints, + RunSetupTests: s.runSetupTests, + } +} + func (s *DestinationModifyService) DestinationID(value string) *DestinationModifyService { s.destinationID = &value return s @@ -57,6 +69,11 @@ func (s *DestinationModifyService) Config(value *DestinationConfig) *Destination return s } +func (s *DestinationModifyService) ConfigCustom(value *map[string]interface{}) *DestinationModifyService { + s.configCustom = value + return s +} + func (s *DestinationModifyService) TrustCertificates(value bool) *DestinationModifyService { s.trustCertificates = &value return s @@ -83,3 +100,15 @@ func (s *DestinationModifyService) Do(ctx context.Context) (DestinationDetailsWi err := s.HttpService.Do(ctx, "PATCH", url, s.request(), nil, 200, &response) return response, err } + +func (s *DestinationModifyService) DoCustom(ctx context.Context) (DestinationDetailsWithSetupTestsCustomResponse, error) { + var response DestinationDetailsWithSetupTestsCustomResponse + + if s.destinationID == nil { + return response, fmt.Errorf("missing required DestinationID") + } + + url := fmt.Sprintf("/destinations/%v", *s.destinationID) + err := s.HttpService.Do(ctx, "PATCH", url, s.requestCustom(), nil, 200, &response) + return response, err +} diff --git a/destinations/destination_modify_test.go b/destinations/destination_modify_test.go index f91dde81..ea5d514e 100644 --- a/destinations/destination_modify_test.go +++ b/destinations/destination_modify_test.go @@ -1,17 +1,17 @@ package destinations_test import ( - "context" - "fmt" - "net/http" - "testing" + "context" + "fmt" + "net/http" + "testing" - "github.com/fivetran/go-fivetran" - "github.com/fivetran/go-fivetran/destinations" - - "github.com/fivetran/go-fivetran/tests/mock" + "github.com/fivetran/go-fivetran" + "github.com/fivetran/go-fivetran/destinations" - testutils "github.com/fivetran/go-fivetran/test_utils" + "github.com/fivetran/go-fivetran/tests/mock" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) const ( @@ -38,6 +38,8 @@ func TestDestinationModifyService(t *testing.T) { ftClient, mockClient := testutils.CreateTestClient() handler := mockClient.When(http.MethodPatch, "/v1/destinations/decent_dropsy").ThenCall( func(req *http.Request) (*http.Response, error) { + body := testutils.RequestBodyToJson(t, req) + assertModifyRequest(t, body) response := mock.NewResponse(req, http.StatusOK, prepareDestinationModifyResponse()) return response, nil }) @@ -77,6 +79,50 @@ func TestDestinationModifyService(t *testing.T) { assertDestinationModifyResponse(t, response) } +func TestDestinationModifyCustomService(t *testing.T) { + // arrange + ftClient, mockClient := testutils.CreateTestClient() + handler := mockClient.When(http.MethodPatch, "/v1/destinations/decent_dropsy").ThenCall( + func(req *http.Request) (*http.Response, error) { + body := testutils.RequestBodyToJson(t, req) + assertModifyRequest(t, body) + response := mock.NewResponse(req, http.StatusOK, prepareDestinationModifyResponse()) + return response, nil + }) + + service := ftClient.NewDestinationModify(). + DestinationID(DESTINATION_MODIFY_ID). + Region(DESTINATION_MODIFY_REGION). + TimeZoneOffset(DESTINATION_MODIFY_TIME_ZONE_OFFSET). + ConfigCustom(&map[string]interface{}{ + "host": DESTINATION_MODIFY_HOST, + "port": 1433, + "database": DESTINATION_MODIFY_DATABASE, + "auth": DESTINATION_MODIFY_AUTH, + "user": DESTINATION_MODIFY_USER, + "password": DESTINATION_MODIFY_PASSWORD, + }). + TrustCertificates(TRUST_CERTIFICATES). + TrustFingerprints(TRUST_FINGERPRINTS). + RunSetupTests(RUN_SETUP_TESTS) + + // act + response, err := service.DoCustom(context.Background()) + + if err != nil { + t.Logf("%+v\n", response) + t.Error(err) + } + + // assert + interactions := mockClient.Interactions() + testutils.AssertEqual(t, len(interactions), 1) + testutils.AssertEqual(t, interactions[0].Handler, handler) + testutils.AssertEqual(t, handler.Interactions, 1) + + assertDestinationModifyCustomResponse(t, response) +} + func prepareDestinationModifyResponse() string { return fmt.Sprintf(`{ "code": "Success", @@ -162,3 +208,45 @@ func assertDestinationModifyResponse(t *testing.T, response destinations.Destina testutils.AssertEqual(t, response.Data.Config.User, DESTINATION_MODIFY_USER) testutils.AssertEqual(t, response.Data.Config.Password, DESTINATION_MODIFY_MASKED) } + +func assertDestinationModifyCustomResponse(t *testing.T, response destinations.DestinationDetailsWithSetupTestsCustomResponse) { + testutils.AssertEqual(t, response.Code, "Success") + testutils.AssertEqual(t, response.Message, "Destination has been updated") + testutils.AssertEqual(t, response.Data.ID, DESTINATION_MODIFY_ID) + testutils.AssertEqual(t, response.Data.GroupID, DESTINATION_MODIFY_ID) + testutils.AssertEqual(t, response.Data.Service, DESTINATION_MODIFY_SERVICE) + testutils.AssertEqual(t, response.Data.Region, DESTINATION_MODIFY_REGION) + testutils.AssertEqual(t, response.Data.TimeZoneOffset, DESTINATION_MODIFY_TIME_ZONE_OFFSET) + testutils.AssertEqual(t, response.Data.SetupStatus, DESTINATION_MODIFY_SETUP_STATUS) + + // assert setup tests + testutils.AssertEqual(t, len(response.Data.SetupTests), 3) + testutils.AssertEqual(t, response.Data.SetupTests[0].Title, DESTINATION_MODIFY_TEST_TITLE_HOST) + testutils.AssertEqual(t, response.Data.SetupTests[0].Status, DESTINATION_MODIFY_TEST_STATUS_PASSED) + testutils.AssertEqual(t, response.Data.SetupTests[1].Title, DESTINATION_MODIFY_TEST_TITLE_DB) + testutils.AssertEqual(t, response.Data.SetupTests[1].Status, DESTINATION_MODIFY_TEST_STATUS_PASSED) + testutils.AssertEqual(t, response.Data.SetupTests[2].Title, DESTINATION_MODIFY_TEST_TITLE_PERM) + testutils.AssertEqual(t, response.Data.SetupTests[2].Status, DESTINATION_MODIFY_TEST_STATUS_PASSED) + + // assert config + testutils.AssertEqual(t, response.Data.Config["host"], DESTINATION_MODIFY_HOST) + testutils.AssertEqual(t, response.Data.Config["port"], DESTINATION_MODIFY_PORT) + testutils.AssertEqual(t, response.Data.Config["database"], DESTINATION_MODIFY_DATABASE) + testutils.AssertEqual(t, response.Data.Config["auth"], DESTINATION_MODIFY_AUTH) + testutils.AssertEqual(t, response.Data.Config["user"], DESTINATION_MODIFY_USER) + testutils.AssertEqual(t, response.Data.Config["password"], DESTINATION_MODIFY_MASKED) +} + +func assertModifyRequest(t *testing.T, request map[string]interface{}) { + c, ok := request["config"] + testutils.AssertEqual(t, ok, true) + config, ok := c.(map[string]interface{}) + testutils.AssertEqual(t, ok, true) + + testutils.AssertKey(t, "host", config, DESTINATION_MODIFY_HOST) + testutils.AssertKey(t, "port", config, float64(1433)) + testutils.AssertKey(t, "database", config, DESTINATION_MODIFY_DATABASE) + testutils.AssertKey(t, "auth", config, DESTINATION_MODIFY_AUTH) + testutils.AssertKey(t, "user", config, DESTINATION_MODIFY_USER) + testutils.AssertKey(t, "password", config, DESTINATION_MODIFY_PASSWORD) +} diff --git a/tests/e2e/destination_create_test.go b/tests/e2e/destination_create_test.go index 89af2980..6c1b664b 100644 --- a/tests/e2e/destination_create_test.go +++ b/tests/e2e/destination_create_test.go @@ -44,3 +44,41 @@ func TestNewDestinationCreateE2E(t *testing.T) { t.Cleanup(func() { testutils.DeleteDestination(t, testutils.PredefinedGroupId) }) } + +func TestNewDestinationCreateCustomE2E(t *testing.T) { + created, err := testutils.Client.NewDestinationCreate(). + GroupID(testutils.PredefinedGroupId). + Service("snowflake"). + TimeZoneOffset("+10"). + RunSetupTests(false). + ConfigCustom(&map[string]interface{}{ + "host": "your-account.snowflakecomputing.com", + "port": 443, + "database": "fivetran", + "auth": "PASSWORD", + "user": "fivetran_user", + "password": "123456", + }). + DoCustom(context.Background()) + + if err != nil { + t.Logf("%+v\n", created) + t.Error(err) + } + + testutils.AssertEqual(t, created.Code, "Success") + testutils.AssertNotEmpty(t, created.Message) + testutils.AssertEqual(t, created.Data.ID, testutils.PredefinedGroupId) + testutils.AssertEqual(t, created.Data.Service, "snowflake") + testutils.AssertEqual(t, created.Data.Region, "GCP_US_EAST4") + testutils.AssertEqual(t, created.Data.TimeZoneOffset, "+10") + testutils.AssertEqual(t, created.Data.SetupStatus, "incomplete") + testutils.AssertEqual(t, created.Data.Config["host"], "your-account.snowflakecomputing.com") + testutils.AssertEqual(t, created.Data.Config["port"], "443") + testutils.AssertEqual(t, created.Data.Config["database"], "fivetran") + testutils.AssertEqual(t, created.Data.Config["auth"], "PASSWORD") + testutils.AssertEqual(t, created.Data.Config["user"], "fivetran_user") + testutils.AssertEqual(t, created.Data.Config["password"], "******") + + t.Cleanup(func() { testutils.DeleteDestination(t, testutils.PredefinedGroupId) }) +} diff --git a/tests/e2e/destination_details_test.go b/tests/e2e/destination_details_test.go index 1da747df..cf8e48d6 100644 --- a/tests/e2e/destination_details_test.go +++ b/tests/e2e/destination_details_test.go @@ -30,3 +30,27 @@ func TestNewDestinationDetailsE2E(t *testing.T) { testutils.AssertEqual(t, details.Data.Config.Host, "your-account.snowflakecomputing.com") testutils.AssertEqual(t, details.Data.Config.User, "fivetran_user") } + +func TestNewDestinationDetailsCustomE2E(t *testing.T) { + destinationId := testutils.CreateTempDestination(t) + + details, err := testutils.Client.NewDestinationDetails().DestinationID(destinationId).DoCustom(context.Background()) + + if err != nil { + t.Logf("%+v\n", details) + t.Error(err) + } + + testutils.AssertEqual(t, details.Code, "Success") + testutils.AssertEqual(t, details.Data.ID, testutils.PredefinedGroupId) + testutils.AssertEqual(t, details.Data.GroupID, testutils.PredefinedGroupId) + testutils.AssertEqual(t, details.Data.Service, "snowflake") + testutils.AssertEqual(t, details.Data.Region, "GCP_US_EAST4") + testutils.AssertEqual(t, details.Data.TimeZoneOffset, "+10") + testutils.AssertEqual(t, details.Data.SetupStatus, "incomplete") + testutils.AssertEqual(t, details.Data.Config["database"], "fivetran") + testutils.AssertEqual(t, details.Data.Config["password"], "******") + testutils.AssertEqual(t, details.Data.Config["port"], "443") + testutils.AssertEqual(t, details.Data.Config["host"], "your-account.snowflakecomputing.com") + testutils.AssertEqual(t, details.Data.Config["user"], "fivetran_user") +} diff --git a/tests/e2e/destination_modify_test.go b/tests/e2e/destination_modify_test.go index 67b7a040..489e1925 100644 --- a/tests/e2e/destination_modify_test.go +++ b/tests/e2e/destination_modify_test.go @@ -41,3 +41,38 @@ func TestNewDestinationModifyE2E(t *testing.T) { testutils.AssertEqual(t, details.Data.Config.User, "fivetran_user_updated") testutils.AssertEqual(t, details.Data.Config.Password, "******") } + +func TestNewDestinationModifyCustomE2E(t *testing.T) { + destinationId := testutils.CreateTempDestination(t) + details, err := testutils.Client.NewDestinationModify().DestinationID(destinationId). + Region("GCP_AUSTRALIA_SOUTHEAST1"). + TimeZoneOffset("+10"). + RunSetupTests(false). + ConfigCustom(&map[string]interface{}{ + "host": "updated_host.snowflakecomputing.com", + "port": 444, + "database": "fivetran_updated", + "auth": "PASSWORD", + "user": "fivetran_user_updated", + "password": "12345678", + }). + DoCustom(context.Background()) + + if err != nil { + t.Logf("%+v\n", details) + t.Error(err) + } + + testutils.AssertEqual(t, details.Code, "Success") + testutils.AssertNotEmpty(t, details.Message) + testutils.AssertEqual(t, details.Data.ID, destinationId) + testutils.AssertEqual(t, details.Data.GroupID, destinationId) + testutils.AssertEqual(t, details.Data.Service, "snowflake") + testutils.AssertEqual(t, details.Data.Region, "GCP_AUSTRALIA_SOUTHEAST1") + testutils.AssertEqual(t, details.Data.TimeZoneOffset, "+10") + testutils.AssertEqual(t, details.Data.Config["host"], "updated_host.snowflakecomputing.com") + testutils.AssertEqual(t, details.Data.Config["port"], "444") + testutils.AssertEqual(t, details.Data.Config["database"], "fivetran_updated") + testutils.AssertEqual(t, details.Data.Config["user"], "fivetran_user_updated") + testutils.AssertEqual(t, details.Data.Config["password"], "******") +}