Skip to content

Commit

Permalink
PoC for env edit in case of AWS
Browse files Browse the repository at this point in the history
  • Loading branch information
gregito committed Nov 20, 2024
1 parent b299e93 commit d99fb70
Show file tree
Hide file tree
Showing 6 changed files with 273 additions and 5 deletions.
96 changes: 96 additions & 0 deletions examples/resources/cdp_environments_aws_environment/resource.tf
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,99 @@ output "environment_name" {
output "crn" {
value = cdp_environments_aws_environment.example.crn
}

output "status" {
value = cdp_environments_aws_environment.example.status
}

output "status_reason" {
value = cdp_environments_aws_environment.example.status_reason
}

output "cloud_platform" {
value = cdp_environments_aws_environment.example.region
}

output "security_access" {
value = cdp_environments_aws_environment.example.security_access
}

output "network_cidr" {
value = cdp_environments_aws_environment.example.network_cidr
}

output "authentication" {
value = cdp_environments_aws_environment.example.authentication
}

output "log_storage" {
value = cdp_environments_aws_environment.example.log_storage
}

output "proxy_config_name" {
value = cdp_environments_aws_environment.example.proxy_config_name
}

output "tags" {
value = cdp_environments_aws_environment.example.tags
}

output "create_private_subnets" {
value = cdp_environments_aws_environment.example.create_private_subnets
}

output "create_service_endpoints" {
value = cdp_environments_aws_environment.example.create_service_endpoints
}

output "s3_guard_table_name" {
value = cdp_environments_aws_environment.example.s3_guard_table_name
}

output "credential_name" {
value = cdp_environments_aws_environment.example.credential_name
}

output "description" {
value = cdp_environments_aws_environment.example.description
}

output "enable_tunnel" {
value = cdp_environments_aws_environment.example.enable_tunnel
}

output "encryption_key_arn" {
value = cdp_environments_aws_environment.example.encryption_key_arn
}

output "endpoint_access_gateway_scheme" {
value = cdp_environments_aws_environment.example.endpoint_access_gateway_scheme
}

output "endpoint_access_gateway_subnet_ids" {
value = cdp_environments_aws_environment.example.endpoint_access_gateway_subnet_ids
}

output "freeipa" {
value = cdp_environments_aws_environment.example.freeipa
}

output "report_deployment_logs" {
value = cdp_environments_aws_environment.example.report_deployment_logs
}

output "subnet_ids" {
value = cdp_environments_aws_environment.example.subnet_ids
}

output "tunnel_type" {
value = cdp_environments_aws_environment.example.tunnel_type
}

output "workload_analytics" {
value = cdp_environments_aws_environment.example.workload_analytics
}

output "vpc_id" {
value = cdp_environments_aws_environment.example.vpc_id
}
2 changes: 2 additions & 0 deletions resources/environments/model_aws_environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,4 +100,6 @@ type SecurityAccess struct {
SecurityGroupIDForKnox types.String `tfsdk:"security_group_id_for_knox"`

SecurityGroupIDsForKnox types.Set `tfsdk:"security_group_ids_for_knox"`

GatewayNodeSecurityGroupID types.String `tfsdk:"gateway_node_security_group_id"`
}
70 changes: 65 additions & 5 deletions resources/environments/resource_aws_environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ package environments

import (
"context"
"reflect"

"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/resource"
Expand Down Expand Up @@ -123,7 +124,65 @@ func (r *awsEnvironmentResource) Read(ctx context.Context, req resource.ReadRequ
}

func (r *awsEnvironmentResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
var plan awsEnvironmentResourceModel
planDiags := req.Plan.Get(ctx, &plan)
resp.Diagnostics.Append(planDiags...)
if resp.Diagnostics.HasError() {
return
}

var state awsEnvironmentResourceModel
stateDiags := req.State.Get(ctx, &state)
resp.Diagnostics.Append(stateDiags...)
if resp.Diagnostics.HasError() {
return
}

if state.EncryptionKeyArn != plan.EncryptionKeyArn {
if err := updateAwsDiskEncryptionParameters(ctx, r.client.Environments, plan); err != nil {
utils.AddEnvironmentDiagnosticsError(err, &resp.Diagnostics, "update disk encryption parameters")
return
}
state.EncryptionKeyArn = plan.EncryptionKeyArn
}
if plan.Authentication != nil && (plan.Authentication != state.Authentication) {
if err := updateSshKey(ctx, r.client.Environments, plan.Authentication, plan.EnvironmentName.ValueStringPointer()); err != nil {
utils.AddEnvironmentDiagnosticsError(err, &resp.Diagnostics, "update SSH key")
return
}
state.Authentication = plan.Authentication
}
if !reflect.DeepEqual(utils.FromSetValueToStringList(plan.SubnetIds), utils.FromSetValueToStringList(state.SubnetIds)) ||
!reflect.DeepEqual(plan.EndpointAccessGatewaySubnetIds, state.EndpointAccessGatewaySubnetIds) {
if err := updateSubnet(ctx, r.client.Environments, plan); err != nil {
utils.AddEnvironmentDiagnosticsError(err, &resp.Diagnostics, "update subnet")
return
}
state.SubnetIds = plan.SubnetIds
state.EndpointAccessGatewaySubnetIds = plan.EndpointAccessGatewaySubnetIds
}
if plan.SecurityAccess != nil && (plan.SecurityAccess != state.SecurityAccess) {
if err := updateSecurityAccess(ctx, r.client.Environments, plan); err != nil {
utils.AddEnvironmentDiagnosticsError(err, &resp.Diagnostics, "update security access")
return
}
state.SecurityAccess = plan.SecurityAccess
}
if !plan.Tags.IsNull() && !reflect.DeepEqual(plan.Tags, state.Tags) {
if err := updateTags(ctx, r.client.Environments, plan); err != nil {
utils.AddEnvironmentDiagnosticsError(err, &resp.Diagnostics, "update tags")
return
}
state.Tags = plan.Tags
}
if plan.ProxyConfigName != state.ProxyConfigName {
if err := updateProxyConfig(ctx, r.client.Environments, plan); err != nil {
utils.AddEnvironmentDiagnosticsError(err, &resp.Diagnostics, "update proxy config")
return
}
state.ProxyConfigName = plan.ProxyConfigName
}
resp.State.Set(ctx, state)
}

func (r *awsEnvironmentResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
Expand Down Expand Up @@ -211,11 +270,12 @@ func toAwsEnvironmentResource(ctx context.Context, env *environmentsmodels.Envir
sgIDsknox = model.SecurityAccess.SecurityGroupIDsForKnox
}
model.SecurityAccess = &SecurityAccess{
Cidr: types.StringValue(env.SecurityAccess.Cidr),
DefaultSecurityGroupID: types.StringValue(env.SecurityAccess.DefaultSecurityGroupID),
DefaultSecurityGroupIDs: dsgIDs,
SecurityGroupIDForKnox: types.StringValue(env.SecurityAccess.SecurityGroupIDForKnox),
SecurityGroupIDsForKnox: sgIDsknox,
Cidr: types.StringValue(env.SecurityAccess.Cidr),
DefaultSecurityGroupID: types.StringValue(env.SecurityAccess.DefaultSecurityGroupID),
DefaultSecurityGroupIDs: dsgIDs,
SecurityGroupIDForKnox: types.StringValue(env.SecurityAccess.SecurityGroupIDForKnox),
SecurityGroupIDsForKnox: sgIDsknox,
GatewayNodeSecurityGroupID: model.SecurityAccess.GatewayNodeSecurityGroupID,
}
}
model.Status = types.StringPointerValue(env.Status)
Expand Down
8 changes: 8 additions & 0 deletions resources/environments/schema_aws_environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ package environments

import (
"context"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/setplanmodifier"

"github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault"
Expand All @@ -37,6 +38,7 @@ var AwsEnvironmentSchema = schema.Schema{
},
},
"crn": schema.StringAttribute{
Optional: true,
Computed: true,
PlanModifiers: []planmodifier.String{
stringplanmodifier.UseStateForUnknown(),
Expand Down Expand Up @@ -224,6 +226,9 @@ var AwsEnvironmentSchema = schema.Schema{
Optional: true,
ElementType: types.StringType,
},
"gateway_node_security_group_id": schema.StringAttribute{
Optional: true,
},
},
},
"status": schema.StringAttribute{
Expand All @@ -242,6 +247,9 @@ var AwsEnvironmentSchema = schema.Schema{
Optional: true,
Computed: true,
ElementType: types.StringType,
PlanModifiers: []planmodifier.Set{
setplanmodifier.UseStateForUnknown(),
},
},
"tags": schema.MapAttribute{
Optional: true,
Expand Down
1 change: 1 addition & 0 deletions resources/environments/schema_freeipa.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ var FreeIpaSchema = schema.SingleNestedAttribute{
},
"instances": schema.SetNestedAttribute{
Computed: true,
Optional: true,
PlanModifiers: []planmodifier.Set{
setplanmodifier.UseStateForUnknown(),
},
Expand Down
101 changes: 101 additions & 0 deletions resources/environments/update_aws_environment_service.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// Copyright 2024 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 environments

import (
"context"

"github.com/hashicorp/terraform-plugin-log/tflog"

environmentsclient "github.com/cloudera/terraform-provider-cdp/cdp-sdk-go/gen/environments/client"
"github.com/cloudera/terraform-provider-cdp/cdp-sdk-go/gen/environments/client/operations"
environmentsmodels "github.com/cloudera/terraform-provider-cdp/cdp-sdk-go/gen/environments/models"
"github.com/cloudera/terraform-provider-cdp/utils"
)

func updateAwsDiskEncryptionParameters(ctx context.Context, client *environmentsclient.Environments, plan awsEnvironmentResourceModel) error {
params := operations.NewUpdateAwsDiskEncryptionParametersParamsWithContext(ctx)
params.WithInput(&environmentsmodels.UpdateAwsDiskEncryptionParametersRequest{
EncryptionKeyArn: plan.EncryptionKeyArn.ValueStringPointer(),
Environment: plan.EnvironmentName.ValueStringPointer(),
})
tflog.Info(ctx, "Updating disk encryption parameters in the environment")
_, err := client.Operations.UpdateAwsDiskEncryptionParameters(params)
return err
}

func updateSshKey(ctx context.Context, client *environmentsclient.Environments, authPlan *Authentication, env *string) error {
params := operations.NewUpdateSSHKeyParamsWithContext(ctx)
if !authPlan.PublicKey.IsNull() && authPlan.PublicKey.ValueString() != "" {
params.WithInput(&environmentsmodels.UpdateSSHKeyRequest{
Environment: env,
NewPublicKey: authPlan.PublicKey.ValueString(),
ExistingPublicKeyID: "",
})
} else {
params.WithInput(&environmentsmodels.UpdateSSHKeyRequest{
Environment: env,
ExistingPublicKeyID: authPlan.PublicKeyID.ValueString(),
NewPublicKey: "",
})
}
tflog.Info(ctx, "Updating SSH key in the environment")
_, err := client.Operations.UpdateSSHKey(params)
return err
}

func updateSubnet(ctx context.Context, client *environmentsclient.Environments, plan awsEnvironmentResourceModel) error {
params := operations.NewUpdateSubnetParamsWithContext(ctx)
params.WithInput(&environmentsmodels.UpdateSubnetRequest{
Environment: plan.EnvironmentName.ValueStringPointer(),
SubnetIds: utils.FromSetValueToStringList(plan.SubnetIds),
EndpointAccessGatewaySubnetIds: utils.FromSetValueToStringList(plan.EndpointAccessGatewaySubnetIds),
})
tflog.Info(ctx, "Updating subnet(s) in the environment")
_, err := client.Operations.UpdateSubnet(params)
return err
}

func updateSecurityAccess(ctx context.Context, client *environmentsclient.Environments, plan awsEnvironmentResourceModel) error {
params := operations.NewUpdateSecurityAccessParamsWithContext(ctx)
params.WithInput(&environmentsmodels.UpdateSecurityAccessRequest{
DefaultSecurityGroupID: plan.SecurityAccess.DefaultSecurityGroupID.ValueStringPointer(),
Environment: plan.EnvironmentName.ValueStringPointer(),
GatewayNodeSecurityGroupID: plan.SecurityAccess.GatewayNodeSecurityGroupID.ValueStringPointer(),
})
tflog.Info(ctx, "Updating security access in the environment")
_, err := client.Operations.UpdateSecurityAccess(params)
return err
}

func updateTags(ctx context.Context, _ *environmentsclient.Environments, _ awsEnvironmentResourceModel) error {
tflog.Error(ctx, "UpdateTags is not implemented yet, it has to be present in BETA SDK beforehand")
return nil
}

func updateProxyConfig(ctx context.Context, client *environmentsclient.Environments, plan awsEnvironmentResourceModel) error {
params := operations.NewUpdateProxyConfigParamsWithContext(ctx)
if plan.ProxyConfigName.IsNull() || plan.ProxyConfigName.ValueString() == "" {
params.WithInput(&environmentsmodels.UpdateProxyConfigRequest{
Environment: plan.EnvironmentName.ValueStringPointer(),
RemoveProxy: true,
})
tflog.Info(ctx, "Removing proxy configuration from the environment")
} else {
params.WithInput(&environmentsmodels.UpdateProxyConfigRequest{
Environment: plan.EnvironmentName.ValueStringPointer(),
ProxyConfigName: plan.ProxyConfigName.ValueString(),
})
tflog.Info(ctx, "Updating proxy configuration in the environment")
}
_, err := client.Operations.UpdateProxyConfig(params)
return err
}

0 comments on commit d99fb70

Please sign in to comment.