From 7df48f85f7a5f53c3fc5c7eae8082edff031968d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Gergely?= Date: Sun, 26 Jan 2025 10:23:53 +0100 Subject: [PATCH] CDPCP-9516 - Implement datasource for listing runtimes --- docs/data-sources/datalake_list_runtimes.md | 48 +++++++++++ .../cdp_datalake_list_runtimes/data-source.tf | 15 ++++ provider/provider.go | 1 + provider/provider_test.go | 1 + resources/datalake/data_source_runtime.go | 82 +++++++++++++++++++ resources/datalake/model_runtime.go | 44 ++++++++++ resources/datalake/model_runtime_test.go | 54 ++++++++++++ resources/datalake/schema_runtime.go | 33 ++++++++ resources/datalake/schema_runtime_test.go | 56 +++++++++++++ 9 files changed, 334 insertions(+) create mode 100644 docs/data-sources/datalake_list_runtimes.md create mode 100644 examples/data-sources/cdp_datalake_list_runtimes/data-source.tf create mode 100644 resources/datalake/data_source_runtime.go create mode 100644 resources/datalake/model_runtime.go create mode 100644 resources/datalake/model_runtime_test.go create mode 100644 resources/datalake/schema_runtime.go create mode 100644 resources/datalake/schema_runtime_test.go diff --git a/docs/data-sources/datalake_list_runtimes.md b/docs/data-sources/datalake_list_runtimes.md new file mode 100644 index 00000000..856ae18c --- /dev/null +++ b/docs/data-sources/datalake_list_runtimes.md @@ -0,0 +1,48 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "cdp_datalake_list_runtimes Data Source - terraform-provider-cdp" +subcategory: "" +description: |- + +--- + +# cdp_datalake_list_runtimes (Data Source) + + + +## Example Usage + +```terraform +// Copyright 2025 Cloudera. All Rights Reserved. +// +// This file is licensed under the Apache License Version 2.0 (the "License"). +// You may not use this file except in compliance with the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0. +// +// This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS +// OF ANY KIND, either express or implied. Refer to the License for the specific +// permissions and limitations governing your use of the file. + +data "cdp_datalake_list_runtimes" "list_runtimes" {} + +output "versions" { + value = data.cdp_datalake_list_runtimes.list_runtimes.versions +} +``` + + +## Schema + +### Read-Only + +- `versions` (Attributes Set) (see [below for nested schema](#nestedatt--versions)) + + +### Nested Schema for `versions` + +Read-Only: + +- `default` (Boolean) +- `version` (String) + + diff --git a/examples/data-sources/cdp_datalake_list_runtimes/data-source.tf b/examples/data-sources/cdp_datalake_list_runtimes/data-source.tf new file mode 100644 index 00000000..7a6eaa42 --- /dev/null +++ b/examples/data-sources/cdp_datalake_list_runtimes/data-source.tf @@ -0,0 +1,15 @@ +// Copyright 2025 Cloudera. All Rights Reserved. +// +// This file is licensed under the Apache License Version 2.0 (the "License"). +// You may not use this file except in compliance with the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0. +// +// This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS +// OF ANY KIND, either express or implied. Refer to the License for the specific +// permissions and limitations governing your use of the file. + +data "cdp_datalake_list_runtimes" "list_runtimes" {} + +output "versions" { + value = data.cdp_datalake_list_runtimes.list_runtimes.versions +} \ No newline at end of file diff --git a/provider/provider.go b/provider/provider.go index 28c95337..0e4e82c3 100644 --- a/provider/provider.go +++ b/provider/provider.go @@ -265,6 +265,7 @@ func (p *CdpProvider) DataSources(_ context.Context) []func() datasource.DataSou return []func() datasource.DataSource{ environments.NewAWSCredentialPrerequisitesDataSource, environments.NewKeytabDataSource, + datalake.NewListRuntimeDataSource, iam.NewGroupDataSource, } } diff --git a/provider/provider_test.go b/provider/provider_test.go index a439e661..c5f1e982 100644 --- a/provider/provider_test.go +++ b/provider/provider_test.go @@ -723,6 +723,7 @@ func TestCdpProvider_DataSources(t *testing.T) { expectedDataSources := []func() datasource.DataSource{ environments.NewAWSCredentialPrerequisitesDataSource, environments.NewKeytabDataSource, + datalake.NewListRuntimeDataSource, iam.NewGroupDataSource, } diff --git a/resources/datalake/data_source_runtime.go b/resources/datalake/data_source_runtime.go new file mode 100644 index 00000000..050bcf16 --- /dev/null +++ b/resources/datalake/data_source_runtime.go @@ -0,0 +1,82 @@ +// Copyright 2025 Cloudera. All Rights Reserved. +// +// This file is licensed under the Apache License Version 2.0 (the "License"). +// You may not use this file except in compliance with the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0. +// +// This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS +// OF ANY KIND, either express or implied. Refer to the License for the specific +// permissions and limitations governing your use of the file. + +package datalake + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-log/tflog" + + "github.com/cloudera/terraform-provider-cdp/cdp-sdk-go/cdp" + "github.com/cloudera/terraform-provider-cdp/cdp-sdk-go/gen/datalake/client" + "github.com/cloudera/terraform-provider-cdp/cdp-sdk-go/gen/datalake/client/operations" + "github.com/cloudera/terraform-provider-cdp/utils" +) + +var ( + _ datasource.DataSource = &runtimeDataSource{} +) + +type runtimeDataSource struct { + client *cdp.Client +} + +func NewListRuntimeDataSource() datasource.DataSource { + return &runtimeDataSource{} +} + +func (p *runtimeDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_datalake_list_runtimes" +} + +func (p *runtimeDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) { + resp.Schema = RuntimeSchema +} + +func (p *runtimeDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { + p.client = utils.GetCdpClientForDataSource(req, resp) +} + +func (p *runtimeDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { + var data RuntimeModel + stuff := req.Config.Get(ctx, &data) + resp.Diagnostics.Append(stuff...) + if resp.Diagnostics.HasError() { + tflog.Error(ctx, "Got Error while trying to get data") + return + } + + runtimes, err := fetchRuntimes(ctx, p.client.Datalake) + + if err != nil { + resp.Diagnostics.AddError("Error during runtime collection", err.Error()) + return + } + + data.Versions = runtimes.Versions + + resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) + if resp.Diagnostics.HasError() { + return + } +} + +func fetchRuntimes(ctx context.Context, client *client.Datalake) (*RuntimeModel, error) { + params := operations.NewListRuntimesParamsWithContext(ctx) + resp, err := client.Operations.ListRuntimes(params) + if err != nil { + tflog.Warn(ctx, fmt.Sprintf("Error during runtime collection due to : %s", err.Error())) + return nil, err + } + return fromListRuntimesResponse(resp.GetPayload()), nil +} diff --git a/resources/datalake/model_runtime.go b/resources/datalake/model_runtime.go new file mode 100644 index 00000000..5465668f --- /dev/null +++ b/resources/datalake/model_runtime.go @@ -0,0 +1,44 @@ +// Copyright 2025 Cloudera. All Rights Reserved. +// +// This file is licensed under the Apache License Version 2.0 (the "License"). +// You may not use this file except in compliance with the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0. +// +// This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS +// OF ANY KIND, either express or implied. Refer to the License for the specific +// permissions and limitations governing your use of the file. + +package datalake + +import ( + "github.com/hashicorp/terraform-plugin-framework/types" + + "github.com/cloudera/terraform-provider-cdp/cdp-sdk-go/gen/datalake/models" +) + +type RuntimeModel struct { + Versions []Runtime `tfsdk:"versions"` +} + +type Runtime struct { + Version types.String `tfsdk:"version"` + Default types.Bool `tfsdk:"default"` +} + +func fromListRuntimesResponse(response *models.ListRuntimesResponse) *RuntimeModel { + if response == nil { + return nil + } + + runtimes := make([]Runtime, len(response.Versions)) + for i, runtime := range response.Versions { + runtimes[i] = Runtime{ + Version: types.StringPointerValue(runtime.RuntimeVersion), + Default: types.BoolPointerValue(runtime.DefaultRuntimeVersion), + } + } + + return &RuntimeModel{ + Versions: runtimes, + } +} diff --git a/resources/datalake/model_runtime_test.go b/resources/datalake/model_runtime_test.go new file mode 100644 index 00000000..3e27d564 --- /dev/null +++ b/resources/datalake/model_runtime_test.go @@ -0,0 +1,54 @@ +// Copyright 2025 Cloudera. All Rights Reserved. +// +// This file is licensed under the Apache License Version 2.0 (the "License"). +// You may not use this file except in compliance with the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0. +// +// This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS +// OF ANY KIND, either express or implied. Refer to the License for the specific +// permissions and limitations governing your use of the file. + +package datalake + +import ( + "reflect" + "testing" + + "github.com/hashicorp/terraform-plugin-framework/types" + + "github.com/cloudera/terraform-provider-cdp/cdp-sdk-go/gen/datalake/models" +) + +func TestNilResponseReturnsNilRuntimeModel(t *testing.T) { + response := (*models.ListRuntimesResponse)(nil) + want := (*RuntimeModel)(nil) + if got := fromListRuntimesResponse(response); !reflect.DeepEqual(got, want) { + t.Errorf("fromListRuntimesResponse() = %v, want %v", got, want) + } +} + +func TestEmptyResponseReturnsEmptyRuntimeModel(t *testing.T) { + response := &models.ListRuntimesResponse{Versions: make([]*models.Runtime, 0)} + want := &RuntimeModel{Versions: []Runtime{}} + if got := fromListRuntimesResponse(response); !reflect.DeepEqual(got, want) { + t.Errorf("fromListRuntimesResponse() = %v, want %v", got, want) + } +} + +func TestValidResponseReturnsCorrectRuntimeModel(t *testing.T) { + versions := make([]*models.Runtime, 1) + def := true + ver := "1.0" + versions[0] = &models.Runtime{RuntimeVersion: &ver, DefaultRuntimeVersion: &def} + response := &models.ListRuntimesResponse{ + Versions: versions, + } + want := &RuntimeModel{ + Versions: []Runtime{ + {Version: types.StringPointerValue(&ver), Default: types.BoolPointerValue(&def)}, + }, + } + if got := fromListRuntimesResponse(response); !reflect.DeepEqual(got, want) { + t.Errorf("fromListRuntimesResponse() = %v, want %v", got, want) + } +} diff --git a/resources/datalake/schema_runtime.go b/resources/datalake/schema_runtime.go new file mode 100644 index 00000000..c9428ea3 --- /dev/null +++ b/resources/datalake/schema_runtime.go @@ -0,0 +1,33 @@ +// Copyright 2025 Cloudera. All Rights Reserved. +// +// This file is licensed under the Apache License Version 2.0 (the "License"). +// You may not use this file except in compliance with the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0. +// +// This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS +// OF ANY KIND, either express or implied. Refer to the License for the specific +// permissions and limitations governing your use of the file. + +package datalake + +import ( + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" +) + +var RuntimeSchema = schema.Schema{ + Attributes: map[string]schema.Attribute{ + "versions": schema.SetNestedAttribute{ + Computed: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "version": schema.StringAttribute{ + Computed: true, + }, + "default": schema.BoolAttribute{ + Computed: true, + }, + }, + }, + }, + }, +} diff --git a/resources/datalake/schema_runtime_test.go b/resources/datalake/schema_runtime_test.go new file mode 100644 index 00000000..a65b0181 --- /dev/null +++ b/resources/datalake/schema_runtime_test.go @@ -0,0 +1,56 @@ +// Copyright 2025 Cloudera. All Rights Reserved. +// +// This file is licensed under the Apache License Version 2.0 (the "License"). +// You may not use this file except in compliance with the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0. +// +// This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS +// OF ANY KIND, either express or implied. Refer to the License for the specific +// permissions and limitations governing your use of the file. + +package datalake + +import ( + "context" + "testing" + + "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" +) + +func TestRuntimeSchemaElements(t *testing.T) { + cases := []TestCaseStructure{ + { + name: "versions should exist", + field: "versions", + computed: true, + shouldBeRequired: false, + attributeType: schema.SetNestedAttribute{}, + }, + } + + underTestAttributes := createFilledRuntimeTestObject() + + for _, test := range cases { + t.Run(test.name, func(t *testing.T) { + if underTestAttributes[test.field] == nil { + t.Errorf("The following field does not exists, however it should: %s", test.field) + t.FailNow() + } + if underTestAttributes[test.field].IsRequired() != test.shouldBeRequired { + t.Errorf("The '%s' filed's >required< property should be: %t", test.field, test.shouldBeRequired) + } + if underTestAttributes[test.field].IsComputed() != test.computed { + t.Errorf("The '%s' filed's >computed< property should be: %t", test.field, test.computed) + } + }) + } +} + +func createFilledRuntimeTestObject() map[string]schema.Attribute { + res := &runtimeDataSource{} + schemaResponse := &datasource.SchemaResponse{} + res.Schema(context.TODO(), datasource.SchemaRequest{}, schemaResponse) + + return schemaResponse.Schema.Attributes +}