Skip to content

Commit

Permalink
CDPCP-9880 - GCP Datalake create/delete/read
Browse files Browse the repository at this point in the history
  • Loading branch information
gregito committed Oct 6, 2023
1 parent 22e7bbc commit 9cc1728
Show file tree
Hide file tree
Showing 6 changed files with 971 additions and 0 deletions.
154 changes: 154 additions & 0 deletions docs/resources/datalake_gcp_datalake.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "cdp_datalake_gcp_datalake Resource - terraform-provider-cdp"
subcategory: ""
description: |-
A Data Lake is a service which provides a protective ring around the data stored in a cloud object store, including authentication, authorization, and governance support.
---

# cdp_datalake_gcp_datalake (Resource)

A Data Lake is a service which provides a protective ring around the data stored in a cloud object store, including authentication, authorization, and governance support.



<!-- schema generated by tfplugindocs -->
## Schema

### Required

- `datalake_name` (String)
- `environment_name` (String)
- `instance_profile` (String)
- `storage_location_base` (String)

### Optional

- `custom_instance_groups` (Attributes Set) (see [below for nested schema](#nestedatt--custom_instance_groups))
- `enable_ranger_raz` (Boolean)
- `image` (Attributes) (see [below for nested schema](#nestedatt--image))
- `java_version` (Number)
- `multi_az` (Boolean)
- `polling_options` (Attributes) Polling related configuration options that could specify various values that will be used during CDP resource creation. (see [below for nested schema](#nestedatt--polling_options))
- `recipes` (Attributes Set) (see [below for nested schema](#nestedatt--recipes))
- `runtime` (String)
- `scale` (String)
- `tags` (Map of String)

### Read-Only

- `certificate_expiration_state` (String)
- `cloudera_manager` (Attributes) (see [below for nested schema](#nestedatt--cloudera_manager))
- `creation_date` (String)
- `crn` (String)
- `endpoints` (Attributes Set) (see [below for nested schema](#nestedatt--endpoints))
- `environment_crn` (String)
- `id` (String) The ID of this resource.
- `instance_groups` (Attributes Set) (see [below for nested schema](#nestedatt--instance_groups))
- `product_versions` (Attributes Set) (see [below for nested schema](#nestedatt--product_versions))
- `status` (String)
- `status_reason` (String)

<a id="nestedatt--custom_instance_groups"></a>
### Nested Schema for `custom_instance_groups`

Required:

- `name` (String)

Optional:

- `instance_type` (String)


<a id="nestedatt--image"></a>
### Nested Schema for `image`

Required:

- `id` (String)

Optional:

- `catalog` (String)


<a id="nestedatt--polling_options"></a>
### Nested Schema for `polling_options`

Optional:

- `polling_timeout` (Number) Timeout value in minutes that specifies for how long should the polling go for resource creation/deletion.


<a id="nestedatt--recipes"></a>
### Nested Schema for `recipes`

Required:

- `instance_group_name` (String)
- `recipe_names` (Attributes Set) (see [below for nested schema](#nestedatt--recipes--recipe_names))

<a id="nestedatt--recipes--recipe_names"></a>
### Nested Schema for `recipes.recipe_names`



<a id="nestedatt--cloudera_manager"></a>
### Nested Schema for `cloudera_manager`

Read-Only:

- `cloudera_manager_repository_url` (String)
- `cloudera_manager_server_url` (String)
- `version` (String)


<a id="nestedatt--endpoints"></a>
### Nested Schema for `endpoints`

Read-Only:

- `display_name` (String)
- `knox_service` (String)
- `mode` (String)
- `open` (Boolean)
- `service_name` (String)
- `service_url` (String)


<a id="nestedatt--instance_groups"></a>
### Nested Schema for `instance_groups`

Read-Only:

- `instances` (Attributes Set) (see [below for nested schema](#nestedatt--instance_groups--instances))
- `name` (String)

<a id="nestedatt--instance_groups--instances"></a>
### Nested Schema for `instance_groups.instances`

Read-Only:

- `discovery_fqdn` (String)
- `id` (String)
- `instance_group` (String)
- `instance_status` (String)
- `instance_type_val` (String)
- `private_ip` (String)
- `public_ip` (String)
- `ssh_port` (Number)
- `state` (String)
- `status_reason` (String)



<a id="nestedatt--product_versions"></a>
### Nested Schema for `product_versions`

Read-Only:

- `name` (String)
- `version` (String)


1 change: 1 addition & 0 deletions provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ func (p *CdpProvider) Resources(_ context.Context) []func() resource.Resource {
environments.NewGcpCredentialResource,
datalake.NewAwsDatalakeResource,
datalake.NewAzureDatalakeResource,
datalake.NewGcpDatalakeResource,
iam.NewGroupResource,
datahub.NewAwsDatahubResource,
datahub.NewAzureDatahubResource,
Expand Down
216 changes: 216 additions & 0 deletions resources/datalake/converter_gcp.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
// Copyright 2023 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"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"

"github.com/hashicorp/terraform-plugin-framework/attr"
"github.com/hashicorp/terraform-plugin-framework/types"

datalakemodels "github.com/cloudera/terraform-provider-cdp/cdp-sdk-go/gen/datalake/models"
"github.com/cloudera/terraform-provider-cdp/utils"
)

func datalakeDetailsToGcpDatalakeResourceModel(ctx context.Context, resp *datalakemodels.DatalakeDetails, model *gcpDatalakeResourceModel, pollingOptions *utils.PollingOptions, diags *diag.Diagnostics) {
model.ID = types.StringPointerValue(resp.Crn)
model.InstanceProfile = types.StringValue(resp.GcpConfiguration.ServiceAccountEmail)
if resp.ClouderaManager != nil {
var cmDiags diag.Diagnostics
model.ClouderaManager, cmDiags = types.ObjectValueFrom(ctx, map[string]attr.Type{
"cloudera_manager_repository_url": types.StringType,
"cloudera_manager_server_url": types.StringType,
"version": types.StringType,
}, &clouderaManagerDetails{
ClouderaManagerRepositoryURL: types.StringPointerValue(resp.ClouderaManager.ClouderaManagerRepositoryURL),
ClouderaManagerServerURL: types.StringValue(resp.ClouderaManager.ClouderaManagerServerURL),
Version: types.StringPointerValue(resp.ClouderaManager.Version),
})
diags.Append(cmDiags...)
}
model.CreationDate = types.StringValue(resp.CreationDate.String())
model.Crn = types.StringPointerValue(resp.Crn)
model.DatalakeName = types.StringPointerValue(resp.DatalakeName)
model.EnableRangerRaz = types.BoolValue(resp.EnableRangerRaz)
model.PollingOptions = pollingOptions
endpoints := make([]*endpoint, len(resp.Endpoints.Endpoints))
for i, v := range resp.Endpoints.Endpoints {
endpoints[i] = &endpoint{
DisplayName: types.StringPointerValue(v.DisplayName),
KnoxService: types.StringPointerValue(v.KnoxService),
Mode: types.StringPointerValue(v.Mode),
Open: types.BoolPointerValue(v.Open),
ServiceName: types.StringPointerValue(v.ServiceName),
ServiceURL: types.StringPointerValue(v.ServiceURL),
}
}
var epDiags diag.Diagnostics
model.Endpoints, epDiags = types.SetValueFrom(ctx, types.ObjectType{
AttrTypes: map[string]attr.Type{
"display_name": types.StringType,
"knox_service": types.StringType,
"mode": types.StringType,
"open": types.BoolType,
"service_name": types.StringType,
"service_url": types.StringType,
},
}, endpoints)
diags.Append(epDiags...)
model.EnvironmentCrn = types.StringValue(resp.EnvironmentCrn)
instanceGroups := make([]*instanceGroup, len(resp.InstanceGroups))
for i, v := range resp.InstanceGroups {
instanceGroups[i] = &instanceGroup{
Name: types.StringPointerValue(v.Name),
}

instances := make([]*instance, len(v.Instances))
for j, ins := range v.Instances {
instances[j] = &instance{
DiscoveryFQDN: types.StringValue(ins.DiscoveryFQDN),
ID: types.StringPointerValue(ins.ID),
InstanceGroup: types.StringValue(ins.InstanceGroup),
InstanceStatus: types.StringValue(string(ins.InstanceStatus)),
InstanceTypeVal: types.StringValue(string(ins.InstanceTypeVal)),
PrivateIP: types.StringValue(ins.PrivateIP),
PublicIP: types.StringValue(ins.PublicIP),
SSHPort: types.Int64Value(int64(ins.SSHPort)),
State: types.StringPointerValue(ins.State),
StatusReason: types.StringValue(ins.StatusReason),
}
}
var instDiags diag.Diagnostics
instanceGroups[i].Instances, instDiags = types.SetValueFrom(ctx, types.ObjectType{
AttrTypes: map[string]attr.Type{
"discovery_fqdn": types.StringType,
"id": types.StringType,
"instance_group": types.StringType,
"instance_status": types.StringType,
"instance_type_val": types.StringType,
"private_ip": types.StringType,
"public_ip": types.StringType,
"ssh_port": types.Int64Type,
"state": types.StringType,
"status_reason": types.StringType,
},
}, instances)
diags.Append(instDiags...)
}
var igDiags diag.Diagnostics
model.InstanceGroups, igDiags = types.SetValueFrom(ctx, types.ObjectType{
AttrTypes: map[string]attr.Type{
"instances": types.SetType{
ElemType: types.ObjectType{
AttrTypes: map[string]attr.Type{
"discovery_fqdn": types.StringType,
"id": types.StringType,
"instance_group": types.StringType,
"instance_status": types.StringType,
"instance_type_val": types.StringType,
"private_ip": types.StringType,
"public_ip": types.StringType,
"ssh_port": types.Int64Type,
"state": types.StringType,
"status_reason": types.StringType,
},
},
},
"name": types.StringType,
},
}, instanceGroups)
diags.Append(igDiags...)
productVersions := make([]*productVersion, len(resp.ProductVersions))
for i, v := range resp.ProductVersions {
productVersions[i] = &productVersion{
Name: types.StringPointerValue(v.Name),
Version: types.StringPointerValue(v.Version),
}
}
var pvDiags diag.Diagnostics
model.ProductVersions, pvDiags = types.SetValueFrom(ctx, types.ObjectType{
AttrTypes: map[string]attr.Type{
"name": types.StringType,
"version": types.StringType,
},
}, productVersions)
diags.Append(pvDiags...)
model.Scale = types.StringValue(string(resp.Shape))
model.Status = types.StringValue(resp.Status)
model.StatusReason = types.StringValue(resp.StatusReason)
if model.CertificateExpirationState.IsUnknown() {
model.CertificateExpirationState = types.StringNull()
}
}

func toGcpDatalakeRequest(ctx context.Context, model *gcpDatalakeResourceModel) *datalakemodels.CreateGCPDatalakeRequest {
req := &datalakemodels.CreateGCPDatalakeRequest{}
if model.CloudProviderConfiguration != nil {
req.CloudProviderConfiguration = &datalakemodels.GCPConfigurationRequest{
ServiceAccountEmail: model.CloudProviderConfiguration.ServiceAccountEmail.ValueStringPointer(),
StorageLocation: model.CloudProviderConfiguration.StorageLocation.ValueStringPointer(),
}
}
req.CustomInstanceGroups = make([]*datalakemodels.SdxInstanceGroupRequest, len(model.CustomInstanceGroups))
for i, v := range model.CustomInstanceGroups {
req.CustomInstanceGroups[i] = &datalakemodels.SdxInstanceGroupRequest{
InstanceType: v.InstanceType.ValueString(),
Name: v.Name.ValueStringPointer(),
}
}
req.DatalakeName = model.DatalakeName.ValueStringPointer()
req.EnableRangerRaz = model.EnableRangerRaz.ValueBool()
req.EnvironmentName = model.EnvironmentName.ValueStringPointer()
if model.Image != nil {
req.Image = &datalakemodels.ImageRequest{
CatalogName: model.Image.CatalogName.ValueStringPointer(),
ID: model.Image.ID.ValueStringPointer(),
}
}
req.JavaVersion = int32(model.JavaVersion.ValueInt64())
req.Recipes = make([]*datalakemodels.InstanceGroupRecipeRequest, len(model.Recipes))
for i, v := range model.Recipes {
req.Recipes[i] = &datalakemodels.InstanceGroupRecipeRequest{
InstanceGroupName: v.InstanceGroupName.ValueStringPointer(),
RecipeNames: utils.FromSetValueToStringList(v.RecipeNames),
}
}
req.Runtime = model.Runtime.ValueString()
req.Scale = datalakemodels.DatalakeScaleType(model.Scale.ValueString())
if !model.Tags.IsNull() {
req.Tags = make([]*datalakemodels.DatalakeResourceGCPTagRequest, len(model.Tags.Elements()))
i := 0
for k, v := range model.Tags.Elements() {
val, diag := v.(basetypes.StringValuable).ToStringValue(ctx)
if !diag.HasError() {
req.Tags[i] = &datalakemodels.DatalakeResourceGCPTagRequest{
Key: &k,
Value: val.ValueStringPointer(),
}
}
i++
}
}
return req
}

func toGcpDatalakeResourceModel(resp *datalakemodels.CreateGCPDatalakeResponse, model *gcpDatalakeResourceModel) {
model.ID = types.StringPointerValue(resp.Datalake.DatalakeName)
model.CertificateExpirationState = types.StringValue(resp.Datalake.CertificateExpirationState)
model.CreationDate = types.StringValue(resp.Datalake.CreationDate.String())
model.Crn = types.StringPointerValue(resp.Datalake.Crn)
model.DatalakeName = types.StringPointerValue(resp.Datalake.DatalakeName)
model.EnableRangerRaz = types.BoolValue(resp.Datalake.EnableRangerRaz)
model.EnvironmentCrn = types.StringValue(resp.Datalake.EnvironmentCrn)
model.MultiAz = types.BoolValue(resp.Datalake.MultiAz)
model.Status = types.StringValue(resp.Datalake.Status)
model.StatusReason = types.StringValue(resp.Datalake.StatusReason)
}
Loading

0 comments on commit 9cc1728

Please sign in to comment.