From 33af410e5e7d98682c58e6cbe68314532a2cbcb5 Mon Sep 17 00:00:00 2001 From: ndopj Date: Wed, 11 Oct 2023 15:42:02 +0200 Subject: [PATCH] feat(data_sources): warehouse exposing MCON's implementation --- monte_carlo/client/monte_carlo_client.go | 24 ++++ monte_carlo/data_sources/warehouse.go | 168 +++++++++++++++++++++++ monte_carlo/provider/provider.go | 3 +- 3 files changed, 194 insertions(+), 1 deletion(-) create mode 100644 monte_carlo/data_sources/warehouse.go diff --git a/monte_carlo/client/monte_carlo_client.go b/monte_carlo/client/monte_carlo_client.go index 3cbffd9..144ec2b 100644 --- a/monte_carlo/client/monte_carlo_client.go +++ b/monte_carlo/client/monte_carlo_client.go @@ -175,3 +175,27 @@ type TestDatabaseCredentials struct { Validations []DatabaseTestDiagnostic } `graphql:"testDatabaseCredentials(connectionType: $connectionType, dbName: $dbName, dbType: $dbType, host: $host, port: $port, user: $user, password: $password)"` } + +type GetTables struct { + GetTables struct { + Edges []struct { + Node struct { + Mcon string + ProjectName string + Dataset string + TableId string + Warehouse struct { + Uuid string + Account struct { + Uuid string + } + } + } + } + PageInfo struct { + StartCursor string + EndCursor string + HasNextPage bool + } + } `graphql:"getTables(dwId: $dwId, first: $first, after: $after, isDeleted: $isDeleted, isExcluded: $isExcluded)"` +} diff --git a/monte_carlo/data_sources/warehouse.go b/monte_carlo/data_sources/warehouse.go new file mode 100644 index 0000000..643ae49 --- /dev/null +++ b/monte_carlo/data_sources/warehouse.go @@ -0,0 +1,168 @@ +package datasources + +import ( + "context" + "fmt" + + "github.com/kiwicom/terraform-provider-montecarlo/monte_carlo/client" + "github.com/kiwicom/terraform-provider-montecarlo/monte_carlo/common" + + "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +var _ datasource.DataSource = &WarehouseDataSource{} + +func NewWarehouseDatasource() datasource.DataSource { + return &WarehouseDataSource{} +} + +type WarehouseDataSource struct { + client client.MonteCarloClient +} + +type WarehouseDataSourceModel struct { + Uuid types.String `tfsdk:"uuid"` + Projects map[string]WarehouseProjectDataSourceModel `tfsdk:"projects"` +} + +type WarehouseProjectDataSourceModel struct { + Mcon types.String `tfsdk:"mcon"` + Datasets map[string]WarehouseDatasetDataSourceModel `tfsdk:"datasets"` +} + +type WarehouseDatasetDataSourceModel struct { + Mcon types.String `tfsdk:"mcon"` + Tables map[string]WarehouseTableDataSourceModel `tfsdk:"tables"` +} + +type WarehouseTableDataSourceModel struct { + Mcon types.String `tfsdk:"mcon"` +} + +func (d *WarehouseDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_warehouse" +} + +func (d *WarehouseDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { + resp.Schema = schema.Schema{ + MarkdownDescription: "", + Attributes: map[string]schema.Attribute{ + "uuid": schema.StringAttribute{ + Required: true, + MarkdownDescription: "", + }, + "projects": schema.MapNestedAttribute{ + Computed: true, + Optional: false, + MarkdownDescription: "", + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "mcon": schema.StringAttribute{ + Required: true, + MarkdownDescription: "", + }, + "datasets": schema.MapNestedAttribute{ + MarkdownDescription: "", + Required: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "mcon": schema.StringAttribute{ + Required: true, + MarkdownDescription: "", + }, + "tables": schema.MapNestedAttribute{ + MarkdownDescription: "", + Required: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "mcon": schema.StringAttribute{ + Required: true, + MarkdownDescription: "", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + } +} + +func (d *WarehouseDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { + if req.ProviderData == nil { + return // prevent 'nil' panic during `terraform plan` + } else if pd, ok := req.ProviderData.(common.ProviderContext); ok { + d.client = pd.MonteCarloClient + } else { + resp.Diagnostics.AddError( + "Unexpected Resource Configure Type", + fmt.Sprintf("Expected ProviderContext, got: %T. Please report this issue to the provider developers.", req.ProviderData), + ) + } +} + +func (d *WarehouseDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { + var data WarehouseDataSourceModel + resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) + if resp.Diagnostics.HasError() { + return + } + + hasNextPage := true + data.Projects = map[string]WarehouseProjectDataSourceModel{} + variables := map[string]interface{}{ + "dwId": client.UUID(data.Uuid.ValueString()), + "first": 500, + "after": (*string)(nil), + "isDeleted": false, + "isExcluded": false, + } + + for hasNextPage { + readResult := client.GetTables{} + if err := d.client.Query(ctx, &readResult, variables); err != nil { + to_print := fmt.Sprintf("MC client 'getTables' query result - %s", err.Error()) + resp.Diagnostics.AddError(to_print, "") + return + } + + hasNextPage = readResult.GetTables.PageInfo.HasNextPage + variables["after"] = readResult.GetTables.PageInfo.EndCursor + + for _, element := range readResult.GetTables.Edges { + project := data.Projects[element.Node.ProjectName] + if project.Datasets == nil { + project.Mcon = types.StringValue(fmt.Sprintf( + "MCON++%s++%s++project++%s", + element.Node.Warehouse.Account.Uuid, + element.Node.Warehouse.Uuid, + element.Node.ProjectName)) + project.Datasets = map[string]WarehouseDatasetDataSourceModel{} + } + + dataset := project.Datasets[element.Node.Dataset] + if dataset.Tables == nil { + dataset.Mcon = types.StringValue(fmt.Sprintf( + "MCON++%s++%s++dataset++%s:%s", + element.Node.Warehouse.Account.Uuid, + element.Node.Warehouse.Uuid, + element.Node.ProjectName, + element.Node.Dataset)) + dataset.Tables = map[string]WarehouseTableDataSourceModel{} + } + + table := dataset.Tables[element.Node.TableId] + table.Mcon = types.StringValue(element.Node.Mcon) + dataset.Tables[element.Node.TableId] = table + project.Datasets[element.Node.Dataset] = dataset + data.Projects[element.Node.ProjectName] = project + } + } + resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) +} diff --git a/monte_carlo/provider/provider.go b/monte_carlo/provider/provider.go index b167282..52af180 100644 --- a/monte_carlo/provider/provider.go +++ b/monte_carlo/provider/provider.go @@ -6,6 +6,7 @@ import ( "github.com/kiwicom/terraform-provider-montecarlo/monte_carlo/client" "github.com/kiwicom/terraform-provider-montecarlo/monte_carlo/common" + datasources "github.com/kiwicom/terraform-provider-montecarlo/monte_carlo/data_sources" "github.com/kiwicom/terraform-provider-montecarlo/monte_carlo/resources" "github.com/hashicorp/terraform-plugin-framework/datasource" @@ -108,7 +109,7 @@ func (p *Provider) Resources(ctx context.Context) []func() resource.Resource { func (p *Provider) DataSources(ctx context.Context) []func() datasource.DataSource { return []func() datasource.DataSource{ - //NewExampleDataSource, + datasources.NewWarehouseDatasource, } }