From 71bbfa9437e33ed261a413e82ec81ae9891ccdac Mon Sep 17 00:00:00 2001 From: PaulomeeCb Date: Mon, 19 Aug 2024 17:19:24 -0700 Subject: [PATCH 01/23] Adding schema and datasources for Azure network peer command --- .../network_peer_command_azure.go | 25 +++ .../datasources/network_peer_command_azure.go | 170 ++++++++++++++++++ internal/provider/provider.go | 1 + internal/schema/network_peer_command_azure.go | 34 ++++ 4 files changed, 230 insertions(+) create mode 100644 internal/api/network_peer/network_peer_command_azure.go create mode 100644 internal/datasources/network_peer_command_azure.go create mode 100644 internal/schema/network_peer_command_azure.go diff --git a/internal/api/network_peer/network_peer_command_azure.go b/internal/api/network_peer/network_peer_command_azure.go new file mode 100644 index 00000000..5facc590 --- /dev/null +++ b/internal/api/network_peer/network_peer_command_azure.go @@ -0,0 +1,25 @@ +package network_peer + +// GetAzureVNetPeeringCommandRequest request to retrieve the role assignment command or script to be executed in the Azure CLI to assign a new network contributor role. +type GetAzureVNetPeeringCommandRequest struct { + // ResourceGroup The resource group name holding the resource you’re connecting with Capella. + ResourceGroup string `json:"resourceGroup"` + + // SubscriptionId Subscription ID is a GUID that uniquely identifies your subscription to use Azure services. To find your subscription ID, see [Find your Azure subscription](https://learn.microsoft.com/en-us/azure/azure-portal/get-subscription-tenant-id#find-your-azure-subscription). + SubscriptionId string `json:"subscriptionId"` + + // TenantId The Azure tenant ID. To find your tenant ID, see [How to find your Azure Active Directory tenant ID](https://learn.microsoft.com/en-us/entra/fundamentals/how-to-find-tenant). + TenantId string `json:"tenantId"` + + // VnetId The VNet ID is the name of the virtual network in Azure. + VnetId string `json:"vnetId"` + + // VnetPeeringServicePrincipal The enterprise application object ID for the Capella service principal. You can find the enterprise application object ID in Azure by selecting Azure Active Directory -> Enterprise applications. Next, select the application name, the object ID is in the Object ID box. + VnetPeeringServicePrincipal string `json:"vnetPeeringServicePrincipal"` +} + +// GetAzureVNetPeeringCommandResponse retrieves the role assignment command or script to be executed in the Azure CLI to assign a new network contributor role. +type GetAzureVNetPeeringCommandResponse struct { + // Command The command to be run by the customer in is their external azure account in order to grant the service principal a network contributor role that is required for VNET peering. + Command string `json:"command"` +} diff --git a/internal/datasources/network_peer_command_azure.go b/internal/datasources/network_peer_command_azure.go new file mode 100644 index 00000000..a7ce98c8 --- /dev/null +++ b/internal/datasources/network_peer_command_azure.go @@ -0,0 +1,170 @@ +package datasources + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + + "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/hashicorp/terraform-plugin-framework/types" + + "github.com/couchbasecloud/terraform-provider-couchbase-capella/internal/api" + network_peer_api "github.com/couchbasecloud/terraform-provider-couchbase-capella/internal/api/network_peer" + "github.com/couchbasecloud/terraform-provider-couchbase-capella/internal/errors" + providerschema "github.com/couchbasecloud/terraform-provider-couchbase-capella/internal/schema" +) + +var ( + _ datasource.DataSource = &AzureNetworkPeerCommand{} + _ datasource.DataSourceWithConfigure = &AzureNetworkPeerCommand{} +) + +// AzureNetworkPeerCommand is the data source implementation. +type AzureNetworkPeerCommand struct { + *providerschema.Data +} + +// NewAzureNetworkPeerCommand is a helper function to simplify the provider implementation. +func NewAzureNetworkPeerCommand() datasource.DataSource { + return &AzureNetworkPeerCommand{} +} + +// Metadata returns the data source type name. +func (a *AzureNetworkPeerCommand) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_azure_network_peer_command" +} + +// Schema defines the schema for the azure network peer command data source. +func (a *AzureNetworkPeerCommand) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) { + resp.Schema = schema.Schema{ + Attributes: map[string]schema.Attribute{ + "organization_id": requiredStringAttribute, + "project_id": requiredStringAttribute, + "cluster_id": requiredStringAttribute, + "tenant_id": requiredStringAttribute, + "subscription_id": requiredStringAttribute, + "resource_group": requiredStringAttribute, + "vnet_id": requiredStringAttribute, + "vnet_peering_service_principal": requiredStringAttribute, + "command": computedStringAttribute, + }, + } +} + +// Read refreshes the Terraform state with the latest data of azure network peer command . +func (a *AzureNetworkPeerCommand) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { + var state providerschema.AzureVNetPeeringCommandRequest + diags := req.Config.Get(ctx, &state) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + err := validateAzurePeeringCommand(state) + if err != nil { + resp.Diagnostics.AddError( + "Error validating Azure private endpoint command request", + "Could not validate Azure private endpoint command request: "+err.Error(), + ) + return + } + + var ( + organizationId = state.OrganizationId.ValueString() + projectId = state.ProjectId.ValueString() + clusterId = state.ClusterId.ValueString() + ) + + AzurePeeringCommandRequest := network_peer_api.GetAzureVNetPeeringCommandRequest{ + ResourceGroup: state.ResourceGroup.ValueString(), + SubscriptionId: state.SubscriptionId.ValueString(), + TenantId: state.TenantId.ValueString(), + VnetId: state.VnetId.ValueString(), + VnetPeeringServicePrincipal: state.VnetPeeringServicePrincipal.ValueString(), + } + + url := fmt.Sprintf("%s/v4/organizations/%s/projects/%s/clusters/%s/networkPeers/networkPeerCommand:", a.HostURL, organizationId, projectId, clusterId) + cfg := api.EndpointCfg{Url: url, Method: http.MethodPost, SuccessStatus: http.StatusOK} + response, err := a.Client.ExecuteWithRetry( + ctx, + cfg, + AzurePeeringCommandRequest, + a.Token, + nil, + ) + if err != nil { + resp.Diagnostics.AddError( + "Error Reading Azure network peer command", + "Could not read Azure network peer command: "+api.ParseError(err), + ) + return + } + + var AzurePeeringCommandResponse network_peer_api.GetAzureVNetPeeringCommandResponse + err = json.Unmarshal(response.Body, &AzurePeeringCommandResponse) + if err != nil { + resp.Diagnostics.AddError( + "Error unmarshalling Azure network peering command response", + "Could not unmarshall Azure network peering command response, unexpected error: "+err.Error(), + ) + return + } + + state.Command = types.StringValue(AzurePeeringCommandResponse.Command) + diags = resp.State.Set(ctx, &state) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } +} + +// Configure adds the provider configured client to the network peer command data source. +func (a *AzureNetworkPeerCommand) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { + if req.ProviderData == nil { + return + } + + data, ok := req.ProviderData.(*providerschema.Data) + if !ok { + resp.Diagnostics.AddError( + "Unexpected Data Source Configure Type", + fmt.Sprintf("Expected *providerschema.Data, got: %T. Please report this issue to the provider developers.", req.ProviderData), + ) + + return + } + + a.Data = data +} + +// validateAzurePeeringCommand ensures organization id, project id, cluster id, and all other required fields are valued. +func validateAzurePeeringCommand(config providerschema.AzureVNetPeeringCommandRequest) error { + if config.OrganizationId.IsNull() { + return errors.ErrOrganizationIdMissing + } + if config.ProjectId.IsNull() { + return errors.ErrProjectIdMissing + } + if config.ClusterId.IsNull() { + return errors.ErrClusterIdMissing + } + //if config.TenantId.IsNull() { + // return errors.ErrTenantIdMissing + //} + //if config.SubscriptionId.IsNull() { + // return errors.ErrSubscriptionIdMissing + //} + //if config.VnetId.IsNull() { + // return errors.ErrVNetIdMissing + //} + //if config.ResourceGroup.IsNull() { + // return errors.ErrResourceGroup + //} + //if config.VnetPeeringServicePrincipal.IsNull() { + // return errors.ErrVnetPeeringServicePrincipal + //} + + return nil +} diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 60989b5b..30a1c855 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -182,6 +182,7 @@ func (p *capellaProvider) DataSources(_ context.Context) []func() datasource.Dat datasources.NewAuditLogEventIDs, datasources.NewAuditLogExport, datasources.NewNetworkPeers, + datasources.NewAzureNetworkPeerCommand, } } diff --git a/internal/schema/network_peer_command_azure.go b/internal/schema/network_peer_command_azure.go new file mode 100644 index 00000000..0dc1f950 --- /dev/null +++ b/internal/schema/network_peer_command_azure.go @@ -0,0 +1,34 @@ +package schema + +import "github.com/hashicorp/terraform-plugin-framework/types" + +// AzureVNetPeeringCommandRequest to retrieve the role assignment command or script to be executed in the Azure CLI to assign a new network contributor role. +type AzureVNetPeeringCommandRequest struct { + + // OrganizationId is the ID of the organization to which the Capella cluster belongs. + OrganizationId types.String `tfsdk:"organization_id"` + + // ProjectId is the ID of the project to which the Capella cluster belongs. + ProjectId types.String `tfsdk:"project_id"` + + // ClusterId is the ID of the cluster for which the network peer needs to be created. + ClusterId types.String `tfsdk:"cluster_id"` + + // ResourceGroup The resource group name holding the resource you’re connecting with Capella. + ResourceGroup types.String `tfsdk:"resource_group"` + + // SubscriptionId Subscription ID is a GUID that uniquely identifies your subscription to use Azure services. To find your subscription ID, see [Find your Azure subscription](https://learn.microsoft.com/en-us/azure/azure-portal/get-subscription-tenant-id#find-your-azure-subscription). + SubscriptionId types.String `tfsdk:"subscription_id"` + + // TenantId The Azure tenant ID. To find your tenant ID, see [How to find your Azure Active Directory tenant ID](https://learn.microsoft.com/en-us/entra/fundamentals/how-to-find-tenant). + TenantId types.String `tfsdk:"tenant_id"` + + // VnetId The VNet ID is the name of the virtual network in Azure. + VnetId types.String `tfsdk:"vnet_id"` + + // VnetPeeringServicePrincipal The enterprise application object ID for the Capella service principal. You can find the enterprise application object ID in Azure by selecting Azure Active Directory -> Enterprise applications. Next, select the application name, the object ID is in the Object ID box. + VnetPeeringServicePrincipal types.String `tfsdk:"vnet_peering_service_principal"` + + // Command is the Azure cli command. + Command types.String `tfsdk:"command"` +} From 767ca75a14845850fb6e80c26e2a18dcf6f14e7f Mon Sep 17 00:00:00 2001 From: PaulomeeCb Date: Mon, 19 Aug 2024 17:20:55 -0700 Subject: [PATCH 02/23] Adding example folder --- examples/network_peer_command_azure/README.md | 1 + .../get_network_peer_command.tf | 3 ++ examples/network_peer_command_azure/main.tf | 11 ++++++ .../terraform.template.tfvars | 9 +++++ .../network_peer_command_azure/variables.tf | 37 +++++++++++++++++++ 5 files changed, 61 insertions(+) create mode 100644 examples/network_peer_command_azure/README.md create mode 100644 examples/network_peer_command_azure/get_network_peer_command.tf create mode 100644 examples/network_peer_command_azure/main.tf create mode 100644 examples/network_peer_command_azure/terraform.template.tfvars create mode 100644 examples/network_peer_command_azure/variables.tf diff --git a/examples/network_peer_command_azure/README.md b/examples/network_peer_command_azure/README.md new file mode 100644 index 00000000..503fa1da --- /dev/null +++ b/examples/network_peer_command_azure/README.md @@ -0,0 +1 @@ +#TODO \ No newline at end of file diff --git a/examples/network_peer_command_azure/get_network_peer_command.tf b/examples/network_peer_command_azure/get_network_peer_command.tf new file mode 100644 index 00000000..ca36a36a --- /dev/null +++ b/examples/network_peer_command_azure/get_network_peer_command.tf @@ -0,0 +1,3 @@ +output "azure_network_peer_command" { + value = data.couchbase-capella_azure_network_peer_command.azure_network_peer_command +} \ No newline at end of file diff --git a/examples/network_peer_command_azure/main.tf b/examples/network_peer_command_azure/main.tf new file mode 100644 index 00000000..b40a0b90 --- /dev/null +++ b/examples/network_peer_command_azure/main.tf @@ -0,0 +1,11 @@ +terraform { + required_providers { + couchbase-capella = { + source = "couchbasecloud/couchbase-capella" + } + } +} + +provider "couchbase-capella" { + authentication_token = var.auth_token +} \ No newline at end of file diff --git a/examples/network_peer_command_azure/terraform.template.tfvars b/examples/network_peer_command_azure/terraform.template.tfvars new file mode 100644 index 00000000..b27edd22 --- /dev/null +++ b/examples/network_peer_command_azure/terraform.template.tfvars @@ -0,0 +1,9 @@ +auth_token = "" +organization_id = "" +project_id = "" +cluster_id = "" +tenant_id = "ffffffff-aaaa-1414-eeee-000000000000" +subscription_id = "ffffffff-aaaa-1414-eeee-000000000000" +resource_group = "sample-resource-group" +vnet_id = "sample-vnet" +vnet_peering_service_principal = "ffffffff-aaaa-1414-eeee-000000000000" \ No newline at end of file diff --git a/examples/network_peer_command_azure/variables.tf b/examples/network_peer_command_azure/variables.tf new file mode 100644 index 00000000..ec45e9ad --- /dev/null +++ b/examples/network_peer_command_azure/variables.tf @@ -0,0 +1,37 @@ +variable "auth_token" { + description = "Authentication API Key" + sensitive = true +} + +variable "organization_id" { + description = "Capella Organization ID" +} + +variable "project_id" { + description = "Capella Project ID" +} + +variable "cluster_id" { + description = "Capella Cluster ID" +} + +variable "tenant_id" { + description = "Azure Tenant ID" +} + +variable "vnet_id" { + description = "Azure virtual network name" +} + +variable "subscription_id" { + description = "Azure Subscription ID" +} + +variable "resource_group" { + description = "Azure resource group name holding the resource you’re connecting with Capella" +} + +variable "vnet_peering_service_principal" { + description = "Azure enterprise application object ID for the Capella service principal" +} + From 823b78debef4cfe764257cebdcb15bfe923f175e Mon Sep 17 00:00:00 2001 From: PaulomeeCb Date: Tue, 20 Aug 2024 12:16:24 -0700 Subject: [PATCH 03/23] Adding Azure VNET peer schema and code --- internal/api/network_peer/network_peer.go | 44 +++++++++++++++-- internal/datasources/network_peer_schema.go | 10 ++++ internal/errors/errors.go | 3 ++ internal/resources/network_peer.go | 25 ++++++++++ internal/resources/network_peer_schema.go | 11 +++++ internal/schema/network_peer.go | 53 +++++++++++++++++++-- 6 files changed, 137 insertions(+), 9 deletions(-) diff --git a/internal/api/network_peer/network_peer.go b/internal/api/network_peer/network_peer.go index cb8143a4..abc75612 100644 --- a/internal/api/network_peer/network_peer.go +++ b/internal/api/network_peer/network_peer.go @@ -22,10 +22,10 @@ type CreateNetworkPeeringRequest struct { // Name is the name of the peering relationship. - The name of the peering relationship must be at least 2 characters long. - The name can not exceed 128 characters. Name string `json:"name"` - // ProviderConfig The config data for a peering relationship for a cluster on AWS, GCP. + // ProviderConfig The config data for a peering relationship for a cluster on AWS, GCP or Azure. ProviderConfig json.RawMessage `json:"providerConfig"` - // ProviderType Type of the cloud provider for which the peering connection is created. Which are- 1. aws 2. gcp + // ProviderType Type of the cloud provider for which the peering connection is created. Which are- 1. aws 2. gcp 3. azure ProviderType string `json:"providerType"` } @@ -55,10 +55,10 @@ type GetNetworkPeeringRecordResponse struct { // Name is the name of the peering relationship. Name string `json:"name"` - // ProviderType Type of the cloud provider for which the peering connection is created. Which are- 1. aws 2. gcp + // ProviderType Type of the cloud provider for which the peering connection is created. Which are- 1. aws 2. gcp 3. azure ProviderType string `json:"providerType"` - // ProviderConfig This provides details about the configuration and the ID of the VPC peer on AWS, GCP. + // ProviderConfig This provides details about the configuration and the ID of the VPC peer on AWS, GCP, or Azure. ProviderConfig json.RawMessage `json:"providerConfig"` // PeeringStatus communicates the state of the VPC peering relationship. It is the state and reasoning for VPC peer. @@ -67,7 +67,7 @@ type GetNetworkPeeringRecordResponse struct { // AWS provides details about the configuration and the ID of the VPC peer on AWS. type AWS struct { - // ProviderId The ID of the VPC peer on GCP. + // ProviderId The ID of the VPC peer on AWS. ProviderId string `json:"ProviderId"` // AWSConfigData is the AWS config data required to establish a VPC peering relationship. AWSConfigData AWSConfigData `json:"AWSConfig"` @@ -81,6 +81,14 @@ type GCP struct { GCPConfigData GCPConfigData `json:"GCPConfig"` } +// Azure provides details about the configuration and the ID of the VNET peer on Azure. +type Azure struct { + // ProviderId The ID of the VNET peer on Azure. + ProviderId string `json:"ProviderId"` + // AzureConfigData Azure config data required to establish a VNET peering relationship. + AzureConfigData AzureConfigData `json:"AzureConfig"` +} + // AWSConfigData is the AWS config data required to establish a VPC peering relationship. // // Refer to the docs for other limitations to AWS VPC Peering - [ref](https://docs.aws.amazon.com/vpc/latest/peering/vpc-peering-basics.html#vpc-peering-limitations). @@ -118,6 +126,25 @@ type GCPConfigData struct { ServiceAccount string `json:"serviceAccount"` } +// AzureConfigData Azure config data required to establish a VNet peering relationship. +// Refer to the docs for other limitations to Azure VNet Peering - [ref](https://learn.microsoft.com/en-us/azure/virtual-network/virtual-network-peering-overview#constraints-for-peered-virtual-networks) +type AzureConfigData struct { + // AzureTenantId The tenant ID. To find your tenant ID, see [How to find your Azure Active Directory tenant ID](https://learn.microsoft.com/en-us/entra/fundamentals/how-to-find-tenant). + AzureTenantId string `json:"azureTenantId"` + + // Cidr The CIDR block from the virtual network that you created in Azure. + Cidr string `json:"cidr"` + + // ResourceGroup The resource group name holding the resource you’re connecting with Capella. + ResourceGroup string `json:"resourceGroup"` + + // SubscriptionId The subscription ID. To find your subscription ID, see [Find your Azure subscription](https://learn.microsoft.com/en-us/azure/azure-portal/get-subscription-tenant-id#find-your-azure-subscription). + SubscriptionId string `json:"subscriptionId"` + + // VnetId The VNet ID is the name of the virtual network peering in Azure. + VnetId string `json:"vnetId"` +} + // AsAWS returns the union data inside the GetNetworkPeeringRecordResponse as a AWS. func (t GetNetworkPeeringRecordResponse) AsAWS() (AWS, error) { var body AWS @@ -131,3 +158,10 @@ func (t GetNetworkPeeringRecordResponse) AsGCP() (GCP, error) { err := json.Unmarshal(t.ProviderConfig, &body) return body, err } + +// AsAZURE returns the union data inside the GetNetworkPeeringRecordResponse_ProviderConfig as a AZURE. +func (t GetNetworkPeeringRecordResponse) AsAZURE() (Azure, error) { + var body Azure + err := json.Unmarshal(t.ProviderConfig, &body) + return body, err +} diff --git a/internal/datasources/network_peer_schema.go b/internal/datasources/network_peer_schema.go index 5d618c21..b6de674c 100644 --- a/internal/datasources/network_peer_schema.go +++ b/internal/datasources/network_peer_schema.go @@ -39,6 +39,16 @@ func NetworkPeerSchema() schema.Schema { "provider_id": computedStringAttribute, }, }, + "azure_config": schema.SingleNestedAttribute{ + Computed: true, + Attributes: map[string]schema.Attribute{ + "tenant_id": computedStringAttribute, + "cidr": computedStringAttribute, + "resource_group": computedStringAttribute, + "subscription_id": computedStringAttribute, + "vnet_id": computedStringAttribute, + }, + }, }, }, "status": schema.SingleNestedAttribute{ diff --git a/internal/errors/errors.go b/internal/errors/errors.go index 21bda94b..c357de0f 100644 --- a/internal/errors/errors.go +++ b/internal/errors/errors.go @@ -148,6 +148,9 @@ var ( // ErrReadingGCPConfig is returned when a GCP disk read fails. ErrReadingGCPConfig = errors.New("failed to read GCP config, please contact Couchbase Capella Support") + // ErrReadingAzureConfig is returned when a GCP disk read fails. + ErrReadingAzureConfig = errors.New("failed to read Azure config, please contact Couchbase Capella Support") + // ErrBucketIdMissing is returned when an expected Bucket Id was not found after an import. ErrBucketIdMissing = errors.New("bucket ID is missing or was passed incorrectly, please check provider documentation for syntax") diff --git a/internal/resources/network_peer.go b/internal/resources/network_peer.go index 9c1a8e0f..566df9ca 100644 --- a/internal/resources/network_peer.go +++ b/internal/resources/network_peer.go @@ -86,6 +86,7 @@ func (n *NetworkPeer) Create(ctx context.Context, req resource.CreateRequest, re networkPeerRequest.ProviderConfig = providerConfigJSON plan.ProviderConfig.GCPConfig = nil + plan.ProviderConfig.AzureConfig = nil } else if plan.ProviderConfig.GCPConfig != nil { gcpConfigJSON := network_peer_api.GCPConfigData{ @@ -104,6 +105,23 @@ func (n *NetworkPeer) Create(ctx context.Context, req resource.CreateRequest, re } networkPeerRequest.ProviderConfig = providerConfigJSON plan.ProviderConfig.AWSConfig = nil + plan.ProviderConfig.AzureConfig = nil + + } else if plan.ProviderConfig.AzureConfig != nil { + azureConfigJSON := network_peer_api.AzureConfigData{ + Cidr: plan.ProviderConfig.AzureConfig.Cidr.ValueString(), + } + providerConfigJSON, err := json.Marshal(azureConfigJSON) + if err != nil { + resp.Diagnostics.AddError( + "Error creating network peer for Azure", + errors.ErrConvertingProviderConfig.Error(), + ) + return + } + networkPeerRequest.ProviderConfig = providerConfigJSON + plan.ProviderConfig.AWSConfig = nil + plan.ProviderConfig.GCPConfig = nil } var ( @@ -398,6 +416,13 @@ func (n *NetworkPeer) getNetworkPeer(ctx context.Context, organizationId, projec return nil, fmt.Errorf("%s: %w", errors.ErrUnmarshallingResponse, err) } + azure, err := networkResp.AsAZURE() + if err == nil && azure.AzureConfigData.AzureTenantId != "" { + networkResp.ProviderType = "azure" + } else if err != nil { + return nil, fmt.Errorf("%s: %w", errors.ErrReadingAzureConfig, err) + } + gcp, err := networkResp.AsGCP() if err == nil && gcp.GCPConfigData.ProjectId != "" { networkResp.ProviderType = "gcp" diff --git a/internal/resources/network_peer_schema.go b/internal/resources/network_peer_schema.go index 8a5137ce..ae059ee3 100644 --- a/internal/resources/network_peer_schema.go +++ b/internal/resources/network_peer_schema.go @@ -54,6 +54,17 @@ func NetworkPeerSchema() schema.Schema { "provider_id": stringAttribute([]string{computed}), }, }, + "azure_config": schema.SingleNestedAttribute{ + Optional: true, + Attributes: map[string]schema.Attribute{ + "tenant_id": stringAttribute([]string{optional}), + "cidr": stringAttribute([]string{required}), + "resource_group": stringAttribute([]string{optional}), + "subscription_id": stringAttribute([]string{optional}), + "vnet_id": stringAttribute([]string{optional}), + "provider_id": stringAttribute([]string{computed}), + }, + }, }, }, "status": schema.SingleNestedAttribute{ diff --git a/internal/schema/network_peer.go b/internal/schema/network_peer.go index ecbb6b59..68ec81a7 100644 --- a/internal/schema/network_peer.go +++ b/internal/schema/network_peer.go @@ -35,9 +35,10 @@ type NetworkPeer struct { //ProviderType is the type of the cloud provider for which the peering connection is created. Which are- // 1. aws // 2. gcp + // 3. azure ProviderType types.String `tfsdk:"provider_type"` - // ProviderConfig This provides details about the configuration and the ID of the VPC peer on AWS, GCP. + // ProviderConfig This provides details about the configuration and the ID of the VPC peer on AWS, GCP, or Azure. ProviderConfig *ProviderConfig `tfsdk:"provider_config"` // Status communicates the state of the VPC peering relationship. It is the state and reasoning for VPC peer. @@ -52,13 +53,16 @@ type PeeringStatus struct { State types.String `tfsdk:"state"` } -// ProviderConfig provides details about the configuration and the ID of the VPC peer on AWS, GCP. +// ProviderConfig provides details about the configuration and the ID of the VPC peer on AWS, GCP, or Azure. type ProviderConfig struct { // AWSConfig AWS config data required to establish a VPC peering relationship. Refer to the docs for other limitations to AWS VPC Peering - [ref](https://docs.aws.amazon.com/vpc/latest/peering/vpc-peering-basics.html#vpc-peering-limitations). AWSConfig *AWSConfig `tfsdk:"aws_config"` // GCPConfig GCP config data required to establish a VPC peering relationship. Refer to the docs for other limitations to GCP VPC Peering - [ref](https://cloud.google.com/vpc/docs/vpc-peering). GCPConfig *GCPConfig `tfsdk:"gcp_config"` + + // AzureConfig Azure config data required to establish a VNet peering relationship. Refer to the docs for other limitations to Azure VNet Peering - [ref](https://learn.microsoft.com/en-us/azure/virtual-network/virtual-network-peering-overview#constraints-for-peered-virtual-networks) + AzureConfig *AzureConfig `tfsdk:"azure_config"` } // AWSConfig AWS config data required to establish a VPC peering relationship. @@ -101,7 +105,34 @@ type GCPConfig struct { // [Reference](https://cloud.google.com/iam/docs/creating-managing-service-accounts#creating) ServiceAccount types.String `tfsdk:"service_account"` - //// ProviderId The ID of the VPC peer on GCP. + // ProviderId The ID of the VPC peer on GCP. + ProviderId types.String `tfsdk:"provider_id"` +} + +// AzureConfig Azure config data required to establish a VNet peering relationship. +// +// Refer to the docs for other limitations to Azure VNet Peering - [ref](https://learn.microsoft.com/en-us/azure/virtual-network/virtual-network-peering-overview#constraints-for-peered-virtual-networks) +type AzureConfig struct { + // AzureTenantId The tenant ID. + // + // To find your tenant ID, see [How to find your Azure Active Directory tenant ID](https://learn.microsoft.com/en-us/entra/fundamentals/how-to-find-tenant). + AzureTenantId types.String `tfsdk:"tenant_id"` + + // Cidr The CIDR block from the virtual network that you created in Azure. + Cidr types.String `tfsdk:"cidr"` + + // ResourceGroup The resource group name holding the resource you’re connecting with Capella. + ResourceGroup types.String `tfsdk:"resource_group"` + + // SubscriptionId The subscription ID. + // + // To find your subscription ID, see [Find your Azure subscription](https://learn.microsoft.com/en-us/azure/azure-portal/get-subscription-tenant-id#find-your-azure-subscription). + SubscriptionId types.String `tfsdk:"subscription_id"` + + // VnetId The VNet ID is the name of the virtual network peering in Azure. + VnetId types.String `tfsdk:"vnet_id"` + + // ProviderId The ID of the VPC peer on Azure. ProviderId types.String `tfsdk:"provider_id"` } @@ -129,7 +160,7 @@ type NetworkPeerData struct { // Name is the Name of the peering relationship. Name types.String `tfsdk:"name"` - // ProviderConfig This provides details about the configuration and the ID of the VPC peer on AWS, GCP. + // ProviderConfig This provides details about the configuration and the ID of the VPC peer on AWS, GCP, or Azure. ProviderConfig ProviderConfig `tfsdk:"provider_config"` // Status communicates the state of the VPC peering relationship. It is the state and reasoning for VPC peer. @@ -229,6 +260,20 @@ func morphToProviderConfig(networkPeer *network_peer_api.GetNetworkPeeringRecord } else if err != nil { return ProviderConfig{}, fmt.Errorf("%s: %w", errors.ErrReadingGCPConfig, err) } + azure, err := networkPeer.AsAZURE() + if err == nil && azure.AzureConfigData.AzureTenantId != "" { + newProviderConfig.AzureConfig = &AzureConfig{ + ProviderId: types.StringValue(azure.ProviderId), + Cidr: types.StringValue(azure.AzureConfigData.Cidr), + SubscriptionId: types.StringValue(azure.AzureConfigData.SubscriptionId), + ResourceGroup: types.StringValue(azure.AzureConfigData.ResourceGroup), + VnetId: types.StringValue(azure.AzureConfigData.VnetId), + AzureTenantId: types.StringValue(azure.AzureConfigData.AzureTenantId), + } + return newProviderConfig, nil + } else if err != nil { + return ProviderConfig{}, fmt.Errorf("%s: %w", errors.ErrReadingAzureConfig, err) + } return newProviderConfig, nil } From 7c4b8e46953a742163617ed05a9307fb957fdcd2 Mon Sep 17 00:00:00 2001 From: PaulomeeCb Date: Tue, 20 Aug 2024 12:17:32 -0700 Subject: [PATCH 04/23] Adding azure to example files --- examples/network_peer/create_network_peer.tf | 12 +++++++++++- examples/network_peer/terraform.template.tfvars | 14 ++++++++++++++ examples/network_peer/variables.tf | 14 ++++++++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/examples/network_peer/create_network_peer.tf b/examples/network_peer/create_network_peer.tf index 1c7987d0..31608d32 100644 --- a/examples/network_peer/create_network_peer.tf +++ b/examples/network_peer/create_network_peer.tf @@ -28,4 +28,14 @@ resource "couchbase-capella_network_peer" "new_network_peer" { # network_name = var.gcp_config.network_name # service_account = var.gcp_config.service_account # cidr = var.gcp_config.cidr -# } \ No newline at end of file +# } + + +# Example Azure Config for creating network peer on Azure. Use this instead of aws_config above if you want to create a network peer for Azure. +# azure_config = { +# tenant_id = var.azure_config.tenant_id +# resource_group = var.azure_config.resource_group +# subscription_id = var.azure_config.subscription_id +# cidr = var.azure_config.cidr +# vnet_id = var.azure_config.vnet_id +# } \ No newline at end of file diff --git a/examples/network_peer/terraform.template.tfvars b/examples/network_peer/terraform.template.tfvars index 5f70eae7..c6ecf48a 100644 --- a/examples/network_peer/terraform.template.tfvars +++ b/examples/network_peer/terraform.template.tfvars @@ -26,3 +26,17 @@ aws_config = { # service_account = "service-account-name@project-id.iam.gserviceaccount.com" # cidr = "10.0.0.0/16" # } + + +# Example Azure Config for creating network peer on Azure. Use this if you want to create a network peer for Azure. +# network_peer = { +# name = "VNETPeerTFTestAZURE" +# provider_type = "azure" +# } +# azure_config = { +# tenant_id = "ffffffff-aaaa-1414-eeee-000000000000" +# subscription_id = "ffffffff-aaaa-1414-eeee-000000000000" +# cidr = "10.0.0.0/16" +# resource_group = "test-rg" +# vnet_id = "ffffffff-aaaa-1414-eeee-000000000000" +# } \ No newline at end of file diff --git a/examples/network_peer/variables.tf b/examples/network_peer/variables.tf index 7c3592a4..9eaf4d4d 100644 --- a/examples/network_peer/variables.tf +++ b/examples/network_peer/variables.tf @@ -45,4 +45,18 @@ variable "aws_config" { # cidr = string # service_account = optional(string) # }) +# } + + +# Reference variable for Azure Config to create a network peer on Azure and use these in the create_network_peer.tf file under provider_config. +# variable "azure_config" { +# description = "Azure configuration details useful for network peer creation" +# +# type = object({ +# tenant_id = optional(string) +# resource_group = optional(string) +# cidr = string +# subscription_id = optional(string) +# vnet_id = optional(string) +# }) # } \ No newline at end of file From d34347417cd7325656c37ffd2eca9395a05aeccc Mon Sep 17 00:00:00 2001 From: PaulomeeCb Date: Tue, 20 Aug 2024 12:18:00 -0700 Subject: [PATCH 05/23] Lint errors removed --- .../terraform.template.tfvars | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/examples/network_peer_command_azure/terraform.template.tfvars b/examples/network_peer_command_azure/terraform.template.tfvars index b27edd22..32aff243 100644 --- a/examples/network_peer_command_azure/terraform.template.tfvars +++ b/examples/network_peer_command_azure/terraform.template.tfvars @@ -1,9 +1,9 @@ -auth_token = "" -organization_id = "" -project_id = "" -cluster_id = "" -tenant_id = "ffffffff-aaaa-1414-eeee-000000000000" -subscription_id = "ffffffff-aaaa-1414-eeee-000000000000" -resource_group = "sample-resource-group" -vnet_id = "sample-vnet" +auth_token = "" +organization_id = "" +project_id = "" +cluster_id = "" +tenant_id = "ffffffff-aaaa-1414-eeee-000000000000" +subscription_id = "ffffffff-aaaa-1414-eeee-000000000000" +resource_group = "sample-resource-group" +vnet_id = "sample-vnet" vnet_peering_service_principal = "ffffffff-aaaa-1414-eeee-000000000000" \ No newline at end of file From 038ebf150bc8701ce5c91e9391718ad1352adcdb Mon Sep 17 00:00:00 2001 From: PaulomeeCb Date: Tue, 20 Aug 2024 12:26:04 -0700 Subject: [PATCH 06/23] Adding errors --- .../datasources/network_peer_command_azure.go | 30 +++++++++---------- internal/errors/errors.go | 15 ++++++++++ 2 files changed, 30 insertions(+), 15 deletions(-) diff --git a/internal/datasources/network_peer_command_azure.go b/internal/datasources/network_peer_command_azure.go index a7ce98c8..00f56bba 100644 --- a/internal/datasources/network_peer_command_azure.go +++ b/internal/datasources/network_peer_command_azure.go @@ -150,21 +150,21 @@ func validateAzurePeeringCommand(config providerschema.AzureVNetPeeringCommandRe if config.ClusterId.IsNull() { return errors.ErrClusterIdMissing } - //if config.TenantId.IsNull() { - // return errors.ErrTenantIdMissing - //} - //if config.SubscriptionId.IsNull() { - // return errors.ErrSubscriptionIdMissing - //} - //if config.VnetId.IsNull() { - // return errors.ErrVNetIdMissing - //} - //if config.ResourceGroup.IsNull() { - // return errors.ErrResourceGroup - //} - //if config.VnetPeeringServicePrincipal.IsNull() { - // return errors.ErrVnetPeeringServicePrincipal - //} + if config.TenantId.IsNull() { + return errors.ErrAzureTenantIdMissing + } + if config.SubscriptionId.IsNull() { + return errors.ErrSubscriptionIdMissing + } + if config.VnetId.IsNull() { + return errors.ErrVNetIdMissing + } + if config.ResourceGroup.IsNull() { + return errors.ErrResourceGroup + } + if config.VnetPeeringServicePrincipal.IsNull() { + return errors.ErrVnetPeeringServicePrincipal + } return nil } diff --git a/internal/errors/errors.go b/internal/errors/errors.go index c357de0f..7747f4f9 100644 --- a/internal/errors/errors.go +++ b/internal/errors/errors.go @@ -27,6 +27,21 @@ var ( // ErrPeerIdMissing is returned when an expected Peer Id was not found after an import. ErrPeerIdMissing = errors.New("peer ID is missing or was passed incorrectly, please check provider documentation for syntax") + // ErrAzureTenantIdMissing is returned when an expected Azure Tenant Id was not found after an import. + ErrAzureTenantIdMissing = errors.New("azure Tenant ID is missing or was passed incorrectly, please check provider documentation for syntax") + + // ErrSubscriptionIdMissing is returned when an expected Azure Subscription Id was not found after an import. + ErrSubscriptionIdMissing = errors.New("azure Subscription ID is missing or was passed incorrectly, please check provider documentation for syntax") + + // ErrVNetIdMissing is returned when an expected Azure Vnet Id was not found after an import. + ErrVNetIdMissing = errors.New("azure Vnet name is missing or was passed incorrectly, please check provider documentation for syntax") + + // ErrResourceGroup is returned when an expected Azure Vnet Resource group was not found after an import. + ErrResourceGroup = errors.New("azure Vnet Resource group is missing or was passed incorrectly, please check provider documentation for syntax") + + // ErrVnetPeeringServicePrincipal is returned when an expected Azure Vnet Service Principal or object id was not found after an import. + ErrVnetPeeringServicePrincipal = errors.New("azure object id or the Azure Vnet Service Principal is missing or was passed incorrectly, please check provider documentation for syntax") + // ErrProjectIdCannotBeEmpty is returned when a Project Id was required for a request but was not included. ErrProjectIdCannotBeEmpty = errors.New("project ID cannot be empty, please contact Couchbase Capella Support") From 4b4ae33f86be2f4830d918097c6fce0456bdf91e Mon Sep 17 00:00:00 2001 From: PaulomeeCb Date: Wed, 21 Aug 2024 11:30:24 -0700 Subject: [PATCH 07/23] Adding data to get command --- .../get_network_peer_command.tf | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/examples/network_peer_command_azure/get_network_peer_command.tf b/examples/network_peer_command_azure/get_network_peer_command.tf index ca36a36a..3d6bf9fa 100644 --- a/examples/network_peer_command_azure/get_network_peer_command.tf +++ b/examples/network_peer_command_azure/get_network_peer_command.tf @@ -1,3 +1,14 @@ output "azure_network_peer_command" { value = data.couchbase-capella_azure_network_peer_command.azure_network_peer_command +} + +data "couchbase-capella_azure_network_peer_command" "azure_network_peer_command" { + organization_id = var.organization_id + project_id = var.project_id + cluster_id = var.cluster_id + tenant_id = var.tenant_id + vnet_id = var.vnet_id + subscription_id = var.subscription_id + resource_group = var.resource_group + vnet_peering_service_principal = var.vnet_peering_service_principal } \ No newline at end of file From 03b39d7516e6e0815b4087a4883ae6095891ae69 Mon Sep 17 00:00:00 2001 From: PaulomeeCb Date: Wed, 21 Aug 2024 12:12:04 -0700 Subject: [PATCH 08/23] Fixing url --- internal/datasources/network_peer_command_azure.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/datasources/network_peer_command_azure.go b/internal/datasources/network_peer_command_azure.go index 00f56bba..33876c49 100644 --- a/internal/datasources/network_peer_command_azure.go +++ b/internal/datasources/network_peer_command_azure.go @@ -65,8 +65,8 @@ func (a *AzureNetworkPeerCommand) Read(ctx context.Context, req datasource.ReadR err := validateAzurePeeringCommand(state) if err != nil { resp.Diagnostics.AddError( - "Error validating Azure private endpoint command request", - "Could not validate Azure private endpoint command request: "+err.Error(), + "Error validating Azure network peer command request", + "Could not validate Azure network peer command request: "+err.Error(), ) return } @@ -85,7 +85,7 @@ func (a *AzureNetworkPeerCommand) Read(ctx context.Context, req datasource.ReadR VnetPeeringServicePrincipal: state.VnetPeeringServicePrincipal.ValueString(), } - url := fmt.Sprintf("%s/v4/organizations/%s/projects/%s/clusters/%s/networkPeers/networkPeerCommand:", a.HostURL, organizationId, projectId, clusterId) + url := fmt.Sprintf("%s/v4/organizations/%s/projects/%s/clusters/%s/networkPeers/networkPeerCommand", a.HostURL, organizationId, projectId, clusterId) cfg := api.EndpointCfg{Url: url, Method: http.MethodPost, SuccessStatus: http.StatusOK} response, err := a.Client.ExecuteWithRetry( ctx, From 865e7df87a4e500d0c7ff31b198afb5318ef0d44 Mon Sep 17 00:00:00 2001 From: PaulomeeCb Date: Wed, 21 Aug 2024 12:13:29 -0700 Subject: [PATCH 09/23] Resolving lint errors --- .../get_network_peer_command.tf | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/examples/network_peer_command_azure/get_network_peer_command.tf b/examples/network_peer_command_azure/get_network_peer_command.tf index 3d6bf9fa..a91926a8 100644 --- a/examples/network_peer_command_azure/get_network_peer_command.tf +++ b/examples/network_peer_command_azure/get_network_peer_command.tf @@ -3,12 +3,12 @@ output "azure_network_peer_command" { } data "couchbase-capella_azure_network_peer_command" "azure_network_peer_command" { - organization_id = var.organization_id - project_id = var.project_id - cluster_id = var.cluster_id - tenant_id = var.tenant_id - vnet_id = var.vnet_id - subscription_id = var.subscription_id - resource_group = var.resource_group - vnet_peering_service_principal = var.vnet_peering_service_principal + organization_id = var.organization_id + project_id = var.project_id + cluster_id = var.cluster_id + tenant_id = var.tenant_id + vnet_id = var.vnet_id + subscription_id = var.subscription_id + resource_group = var.resource_group + vnet_peering_service_principal = var.vnet_peering_service_principal } \ No newline at end of file From 33ad603576ece7de491ee5c31ac92bdd58f85e94 Mon Sep 17 00:00:00 2001 From: PaulomeeCb Date: Fri, 23 Aug 2024 17:17:56 -0700 Subject: [PATCH 10/23] Resolving errors in implementation --- internal/datasources/network_peer_schema.go | 1 + internal/resources/network_peer.go | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/internal/datasources/network_peer_schema.go b/internal/datasources/network_peer_schema.go index b6de674c..97873965 100644 --- a/internal/datasources/network_peer_schema.go +++ b/internal/datasources/network_peer_schema.go @@ -47,6 +47,7 @@ func NetworkPeerSchema() schema.Schema { "resource_group": computedStringAttribute, "subscription_id": computedStringAttribute, "vnet_id": computedStringAttribute, + "provider_id": computedStringAttribute, }, }, }, diff --git a/internal/resources/network_peer.go b/internal/resources/network_peer.go index 566df9ca..b12b9cb7 100644 --- a/internal/resources/network_peer.go +++ b/internal/resources/network_peer.go @@ -109,7 +109,11 @@ func (n *NetworkPeer) Create(ctx context.Context, req resource.CreateRequest, re } else if plan.ProviderConfig.AzureConfig != nil { azureConfigJSON := network_peer_api.AzureConfigData{ - Cidr: plan.ProviderConfig.AzureConfig.Cidr.ValueString(), + AzureTenantId: plan.ProviderConfig.AzureConfig.AzureTenantId.ValueString(), + ResourceGroup: plan.ProviderConfig.AzureConfig.ResourceGroup.ValueString(), + SubscriptionId: plan.ProviderConfig.AzureConfig.SubscriptionId.ValueString(), + VnetId: plan.ProviderConfig.AzureConfig.VnetId.ValueString(), + Cidr: plan.ProviderConfig.AzureConfig.Cidr.ValueString(), } providerConfigJSON, err := json.Marshal(azureConfigJSON) if err != nil { From 2a0ffcaf4da54bed0d0f2e88ca1f224b1dbb1e53 Mon Sep 17 00:00:00 2001 From: PaulomeeCb Date: Fri, 23 Aug 2024 17:20:26 -0700 Subject: [PATCH 11/23] README files --- examples/network_peer/README.md | 829 +++++++++++++++++- examples/network_peer_command_azure/README.md | 70 +- 2 files changed, 896 insertions(+), 3 deletions(-) diff --git a/examples/network_peer/README.md b/examples/network_peer/README.md index 2594f617..53d942a0 100644 --- a/examples/network_peer/README.md +++ b/examples/network_peer/README.md @@ -1,6 +1,6 @@ # Capella Network Peers Example AWS -This example shows how to create and manage Network Peers in Capella. +This example shows how to create and manage Network Peers in Capella for AWS. This creates a new network peer in the selected Capella AWS cluster and lists existing network peers in the cluster. It uses the cluster id to create and list network peers. @@ -680,7 +680,7 @@ Destroy complete! Resources: 1 destroyed. # Capella Network Peers Example GCP -This example shows how to create and manage Network Peers in Capella. +This example shows how to create and manage Network Peers in Capella for GCP. This creates a new network peer in the selected Capella GCP cluster and lists existing network peers in the cluster. It uses the cluster id to create and list network peers. @@ -1361,4 +1361,829 @@ couchbase-capella_network_peer.new_network_peer: Destruction complete after 14s Destroy complete! Resources: 1 destroyed. +``` + +# Capella Network Peers Example Azure + +This example shows how to create and manage Network Peers in Capella for Azure. + +This creates a new network peer in the selected Capella Azure cluster and lists existing network peers in the cluster. It uses the cluster id to create and list network peers. + +To run, configure your Couchbase Capella provider as described in README in the root of this project. + +# Example Walkthrough + +In this example, we are going to do the following. + +1. CREATE: Create a new network peer in Capella as stated in the `create_network_peer.tf` file. +2. UPDATE: Update the network peer configuration using Terraform. +3. LIST: List existing network peer in Capella as stated in the `list_network_peers.tf` file. +4. IMPORT: Import a network peer that exists in Capella but not in the terraform state file. +5. DELETE: Delete the newly created network peer from Capella. + +If you check the `terraform.template.tfvars` file - Make sure you copy the file to `terraform.tfvars` and update the values of the variables as per the correct organization access. + +## CREATE & LIST +### View the plan for the resources that Terraform will create + +Command: `terraform plan` + +Sample Output: +``` +$ terraform plan +╷ +│ Warning: Provider development overrides are in effect +│ +│ The following provider development overrides are set in the CLI configuration: +│ - couchbasecloud/couchbase-capella in /Users/paulomee.de/go/bin +│ +│ The behavior may therefore not match any released version of the provider and applying changes may cause the state to become incompatible with published releases. +╵ +data.couchbase-capella_network_peers.existing_network_peers: Reading... +data.couchbase-capella_network_peers.existing_network_peers: Read complete after 0s + +Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + + create + +Terraform will perform the following actions: + + # couchbase-capella_network_peer.new_network_peer will be created + + resource "couchbase-capella_network_peer" "new_network_peer" { + + audit = (known after apply) + + cluster_id = "ffffffff-aaaa-1414-eeee-00000000000" + + commands = (known after apply) + + id = (known after apply) + + name = "VNETPeerTFTestAZURE" + + organization_id = "ffffffff-aaaa-1414-eeee-00000000000" + + project_id = "ffffffff-aaaa-1414-eeee-00000000000" + + provider_config = { + + azure_config = { + + cidr = "10.6.0.0/16" + + provider_id = (known after apply) + + resource_group = "test-rg" + + subscription_id = "ffffffff-aaaa-1414-eeee-00000000000" + + tenant_id = "ffffffff-aaaa-1414-eeee-00000000000" + + vnet_id = "test-vnet" + } + } + + provider_type = "azure" + + status = (known after apply) + } + +Plan: 1 to add, 0 to change, 0 to destroy. + +Changes to Outputs: + + network_peers_list = { + + cluster_id = "ffffffff-aaaa-1414-eeee-00000000000" + + data = [ + + { + + audit = { + + created_at = "2024-08-23 23:30:39.790107885 +0000 UTC" + + created_by = "s10qrydhDaic9GsWZ6BYpJfSK7wARDCv" + + modified_at = "2024-08-23 23:35:39.359925093 +0000 UTC" + + modified_by = "ffffffff-aaaa-1414-eeee-00000000000" + + version = 6 + } + + id = "ffffffff-aaaa-1414-eeee-00000000000" + + name = "VNETPeerTFTestAZURE" + + provider_config = { + + aws_config = null + + azure_config = { + + cidr = "10.6.0.0/16" + + provider_id = "" + + resource_group = "\"test-rg\"" + + subscription_id = "\"ffffffff-aaaa-1414-eeee-00000000000\"" + + tenant_id = "\"ffffffff-aaaa-1414-eeee-00000000000\"" + + vnet_id = "\"test-vnet\"" + } + + gcp_config = null + } + + status = { + + reasoning = "" + + state = "failed" + } + }, + ] + + organization_id = "ffffffff-aaaa-1414-eeee-00000000000" + + project_id = "ffffffff-aaaa-1414-eeee-00000000000" + } + + new_network_peer = { + + audit = (known after apply) + + cluster_id = "ffffffff-aaaa-1414-eeee-00000000000" + + commands = (known after apply) + + id = (known after apply) + + name = "VNETPeerTFTestAZURE" + + organization_id = "ffffffff-aaaa-1414-eeee-00000000000" + + project_id = "ffffffff-aaaa-1414-eeee-00000000000" + + provider_config = { + + aws_config = null + + azure_config = { + + cidr = "10.6.0.0/16" + + provider_id = (known after apply) + + resource_group = "test-rg" + + subscription_id = "ffffffff-aaaa-1414-eeee-00000000000" + + tenant_id = "ffffffff-aaaa-1414-eeee-00000000000" + + vnet_id = "test-vnet" + } + + gcp_config = null + } + + provider_type = "azure" + + status = (known after apply) + } + + peer_id = (known after apply) + +───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + +Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now. + +``` + +### Apply the Plan, in order to create a new network peer + +Command: `terraform apply` + +Sample Output: +``` +$ terraform apply +╷ +│ Warning: Provider development overrides are in effect +│ +│ The following provider development overrides are set in the CLI configuration: +│ - couchbasecloud/couchbase-capella in /Users/paulomee.de/go/bin +│ +│ The behavior may therefore not match any released version of the provider and applying changes may cause the state to become incompatible with published releases. +╵ +data.couchbase-capella_network_peers.existing_network_peers: Reading... +data.couchbase-capella_network_peers.existing_network_peers: Read complete after 0s + +Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + + create + +Terraform will perform the following actions: + + # couchbase-capella_network_peer.new_network_peer will be created + + resource "couchbase-capella_network_peer" "new_network_peer" { + + audit = (known after apply) + + cluster_id = "ffffffff-aaaa-1414-eeee-00000000000" + + commands = (known after apply) + + id = (known after apply) + + name = "VNETPeerTFTestAZURE" + + organization_id = "ffffffff-aaaa-1414-eeee-00000000000" + + project_id = "ffffffff-aaaa-1414-eeee-00000000000" + + provider_config = { + + azure_config = { + + cidr = "10.6.0.0/16" + + provider_id = (known after apply) + + resource_group = "test-rg" + + subscription_id = "ffffffff-aaaa-1414-eeee-00000000000" + + tenant_id = "ffffffff-aaaa-1414-eeee-00000000000" + + vnet_id = "test-vnet" + } + } + + provider_type = "azure" + + status = (known after apply) + } + +Plan: 1 to add, 0 to change, 0 to destroy. + +Changes to Outputs: + + network_peers_list = { + + cluster_id = "ffffffff-aaaa-1414-eeee-00000000000" + + data = [ + + { + + audit = { + + created_at = "2024-08-23 23:30:39.790107885 +0000 UTC" + + created_by = "s10qrydhDaic9GsWZ6BYpJfSK7wARDCv" + + modified_at = "2024-08-23 23:35:39.359925093 +0000 UTC" + + modified_by = "ffffffff-aaaa-1414-eeee-00000000000" + + version = 6 + } + + id = "ffffffff-aaaa-1414-eeee-00000000000" + + name = "VNETPeerTFTestAZURE" + + provider_config = { + + aws_config = null + + azure_config = { + + cidr = "10.6.0.0/16" + + provider_id = "" + + resource_group = "\"test-rg\"" + + subscription_id = "\"ffffffff-aaaa-1414-eeee-00000000000\"" + + tenant_id = "\"ffffffff-aaaa-1414-eeee-00000000000\"" + + vnet_id = "\"test-vnet\"" + } + + gcp_config = null + } + + status = { + + reasoning = "" + + state = "failed" + } + }, + ] + + organization_id = "ffffffff-aaaa-1414-eeee-00000000000" + + project_id = "ffffffff-aaaa-1414-eeee-00000000000" + } + + new_network_peer = { + + audit = (known after apply) + + cluster_id = "ffffffff-aaaa-1414-eeee-00000000000" + + commands = (known after apply) + + id = (known after apply) + + name = "VNETPeerTFTestAZURE" + + organization_id = "ffffffff-aaaa-1414-eeee-00000000000" + + project_id = "ffffffff-aaaa-1414-eeee-00000000000" + + provider_config = { + + aws_config = null + + azure_config = { + + cidr = "10.6.0.0/16" + + provider_id = (known after apply) + + resource_group = "test-rg" + + subscription_id = "ffffffff-aaaa-1414-eeee-00000000000" + + tenant_id = "ffffffff-aaaa-1414-eeee-00000000000" + + vnet_id = "test-vnet" + } + + gcp_config = null + } + + provider_type = "azure" + + status = (known after apply) + } + + peer_id = (known after apply) + +Do you want to perform these actions? + Terraform will perform the actions described above. + Only 'yes' will be accepted to approve. + + Enter a value: yes + +couchbase-capella_network_peer.new_network_peer: Creating... +couchbase-capella_network_peer.new_network_peer: Still creating... [10s elapsed] +couchbase-capella_network_peer.new_network_peer: Still creating... [20s elapsed] +couchbase-capella_network_peer.new_network_peer: Still creating... [30s elapsed] +couchbase-capella_network_peer.new_network_peer: Still creating... [40s elapsed] +couchbase-capella_network_peer.new_network_peer: Creation complete after 43s [id=ffffffff-aaaa-1414-eeee-00000000000] + +Apply complete! Resources: 1 added, 0 changed, 0 destroyed. + +Outputs: + +network_peers_list = { + "cluster_id" = "ffffffff-aaaa-1414-eeee-00000000000" + "data" = tolist([ + { + "audit" = { + "created_at" = "2024-08-23 23:30:39.790107885 +0000 UTC" + "created_by" = "s10qrydhDaic9GsWZ6BYpJfSK7wARDCv" + "modified_at" = "2024-08-23 23:35:39.359925093 +0000 UTC" + "modified_by" = "ffffffff-aaaa-1414-eeee-00000000000" + "version" = 6 + } + "id" = "ffffffff-aaaa-1414-eeee-00000000000" + "name" = "VNETPeerTFTestAZURE" + "provider_config" = { + "aws_config" = null /* object */ + "azure_config" = { + "cidr" = "10.6.0.0/16" + "provider_id" = "" + "resource_group" = "\"test-rg\"" + "subscription_id" = "\"ffffffff-aaaa-1414-eeee-00000000000\"" + "tenant_id" = "\"ffffffff-aaaa-1414-eeee-00000000000\"" + "vnet_id" = "\"test-vnet\"" + } + "gcp_config" = null /* object */ + } + "status" = { + "reasoning" = "" + "state" = "failed" + } + }, + ]) + "organization_id" = "ffffffff-aaaa-1414-eeee-00000000000" + "project_id" = "ffffffff-aaaa-1414-eeee-00000000000" +} +new_network_peer = { + "audit" = { + "created_at" = "2024-08-24 00:01:23.524305127 +0000 UTC" + "created_by" = "s10qrydhDaic9GsWZ6BYpJfSK7wARDCv" + "modified_at" = "2024-08-24 00:02:05.606678591 +0000 UTC" + "modified_by" = "s10qrydhDaic9GsWZ6BYpJfSK7wARDCv" + "version" = 2 + } + "cluster_id" = "ffffffff-aaaa-1414-eeee-00000000000" + "commands" = toset([]) + "id" = "ffffffff-aaaa-1414-eeee-00000000000" + "name" = "VNETPeerTFTestAZURE" + "organization_id" = "ffffffff-aaaa-1414-eeee-00000000000" + "project_id" = "ffffffff-aaaa-1414-eeee-00000000000" + "provider_config" = { + "aws_config" = null /* object */ + "azure_config" = { + "cidr" = "10.6.0.0/16" + "provider_id" = "/subscriptions/ffffffff-aaaa-1414-eeee-00000000000/resourceGroups/rg-ffffffff-aaaa-1414-eeee-00000000000/providers/Microsoft.Network/virtualNetworks/cc-ffffffff-aaaa-1414-eeee-00000000000/virtualNetworkPeerings/cc-ffffffff-aaaa-1414-eeee-00000000000-test-vnet" + "resource_group" = "test-rg" + "subscription_id" = "ffffffff-aaaa-1414-eeee-00000000000" + "tenant_id" = "ffffffff-aaaa-1414-eeee-00000000000" + "vnet_id" = "test-vnet" + } + "gcp_config" = null /* object */ + } + "provider_type" = "azure" + "status" = { + "reasoning" = "" + "state" = "complete" + } +} +peer_id = "ffffffff-aaaa-1414-eeee-00000000000" + +``` + +### Note the peer id for the new Network Peer +Command: `terraform output new_network_peer` + +Sample Output: +``` +$ terraform output new_network_peer +{ + "audit" = { + "created_at" = "2024-08-24 00:01:23.524305127 +0000 UTC" + "created_by" = "s10qrydhDaic9GsWZ6BYpJfSK7wARDCv" + "modified_at" = "2024-08-24 00:02:05.606678591 +0000 UTC" + "modified_by" = "s10qrydhDaic9GsWZ6BYpJfSK7wARDCv" + "version" = 2 + } + "cluster_id" = "ffffffff-aaaa-1414-eeee-00000000000" + "commands" = toset([]) + "id" = "ffffffff-aaaa-1414-eeee-00000000000" + "name" = "VNETPeerTFTestAZURE" + "organization_id" = "ffffffff-aaaa-1414-eeee-00000000000" + "project_id" = "ffffffff-aaaa-1414-eeee-00000000000" + "provider_config" = { + "aws_config" = null /* object */ + "azure_config" = { + "cidr" = "10.6.0.0/16" + "provider_id" = "/subscriptions/ffffffff-aaaa-1414-eeee-00000000000/resourceGroups/rg-ffffffff-aaaa-1414-eeee-00000000000/providers/Microsoft.Network/virtualNetworks/cc-ffffffff-aaaa-1414-eeee-00000000000/virtualNetworkPeerings/cc-ffffffff-aaaa-1414-eeee-00000000000-test-vnet" + "resource_group" = "test-rg" + "subscription_id" = "ffffffff-aaaa-1414-eeee-00000000000" + "tenant_id" = "ffffffff-aaaa-1414-eeee-00000000000" + "vnet_id" = "test-vnet" + } + "gcp_config" = null /* object */ + } + "provider_type" = "azure" + "status" = { + "reasoning" = "" + "state" = "complete" + } +} + +``` + +In this case, the peer ID for my new network peer is `ffffffff-aaaa-1414-eeee-000000000000` + +### List the resources that are present in the Terraform State file. + +Command: `terraform state list` + +Sample Output: +``` +$ terraform state list +data.couchbase-capella_network_peers.existing_network_peers +couchbase-capella_network_peer.new_network_peer + +``` + +## IMPORT +### Remove the resource `new_network_peer` from the Terraform State file + +Command: `terraform state rm couchbase-capella_network_peer.new_network_peer` + +Sample Output: +``` +$ terraform state rm couchbase-capella_network_peer.new_network_peer +Removed couchbase-capella_network_peer.new_network_peer +Successfully removed 1 resource instance(s). + +``` + +Please note, this command will only remove the resource from the Terraform State file, but in reality, the resource exists in Capella. + +### Now, let's import the resource in Terraform + +Command: `terraform import couchbase-capella_network_peer.new_network_peer id=,cluster_id=,project_id=,organization_id=` + +In this case, the complete command is: +`terraform import couchbase-capella_network_peer.new_network_peer id=ffffffff-aaaa-1414-eeee-000000000000,cluster_id=ffffffff-aaaa-1414-eeee-000000000000,project_id=ffffffff-aaaa-1414-eeee-000000000000,organization_id=ffffffff-aaaa-1414-eeee-000000000000` + +Sample Output: +``` +$ terraform import couchbase-capella_network_peer.new_network_peer id=ffffffff-aaaa-1414-eeee-000000000000,cluster_id=ffffffff-aaaa-1414-eeee-000000000000,project_id=ffffffff-aaaa-1414-eeee-000000000000,organization_id=ffffffff-aaaa-1414-eeee-000000000000 + +couchbase-capella_network_peer.new_network_peer: Importing from ID "id=ffffffff-aaaa-1414-eeee-000000000000,cluster_id=ffffffff-aaaa-1414-eeee-000000000000,project_id=ffffffff-aaaa-1414-eeee-000000000000,organization_id=ffffffff-aaaa-1414-eeee-000000000000"... +data.couchbase-capella_network_peers.existing_network_peers: Reading... +couchbase-capella_network_peer.new_network_peer: Import prepared! + Prepared couchbase-capella_network_peer for import +couchbase-capella_network_peer.new_network_peer: Refreshing state... [id=id=ffffffff-aaaa-1414-eeee-000000000000,cluster_id=ffffffff-aaaa-1414-eeee-000000000000,project_id=ffffffff-aaaa-1414-eeee-000000000000,organization_id=ffffffff-aaaa-1414-eeee-000000000000] +data.couchbase-capella_network_peers.existing_network_peers: Read complete after 0s + +Import successful! + +The resources that were imported are shown above. These resources are now in +your Terraform state and will henceforth be managed by Terraform. + +``` + +Here, we pass the IDs as a single comma-separated string. +The first ID in the string is the peer ID i.e. the ID of the resource that we want to import. +The second ID is the cluster ID i.e. the ID of the cluster to which the network peer belongs. +The third ID is the project ID i.e. the ID of the project to which the cluster belongs. +The fourth ID is the organization ID i.e. the ID of the organization to which the project belongs. + +### Let's run a terraform plan to confirm that the import was successful and no resource states were impacted + +Command: `terraform plan` + +Sample Output: +``` +$ terraform plan +╷ +│ Warning: Provider development overrides are in effect +│ +│ The following provider development overrides are set in the CLI configuration: +│ - couchbasecloud/couchbase-capella in /Users/$USER/go/bin +│ +│ The behavior may therefore not match any released version of the provider and applying changes may cause the state to become incompatible with published releases. +╵ +data.couchbase-capella_network_peers.existing_network_peers: Reading... +couchbase-capella_network_peer.new_network_peer: Refreshing state... [id=ffffffff-aaaa-1414-eeee-000000000000] +data.couchbase-capella_network_peers.existing_network_peers: Read complete after 0s + +No changes. Your infrastructure matches the configuration. + +Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed. + +``` + +## UPDATE +### Let us edit the terraform.tfvars file to change the network peer configuration settings. + +# Changed the network_name, destroys and forces replacement + +Sample Output: +``` +$ terraform apply +╷ +│ Warning: Provider development overrides are in effect +│ +│ The following provider development overrides are set in the CLI configuration: +│ - couchbasecloud/couchbase-capella in /Users/paulomee.de/go/bin +│ +│ The behavior may therefore not match any released version of the provider and applying changes may cause the state to become incompatible with published releases. +╵ +data.couchbase-capella_network_peers.existing_network_peers: Reading... +couchbase-capella_network_peer.new_network_peer: Refreshing state... [id=ffffffff-aaaa-1414-eeee-00000000000] +data.couchbase-capella_network_peers.existing_network_peers: Read complete after 1s + +Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: +-/+ destroy and then create replacement + +Terraform will perform the following actions: + + # couchbase-capella_network_peer.new_network_peer must be replaced +-/+ resource "couchbase-capella_network_peer" "new_network_peer" { + ~ audit = { + ~ created_at = "2024-08-24 00:01:23.524305127 +0000 UTC" -> (known after apply) + ~ created_by = "s10qrydhDaic9GsWZ6BYpJfSK7wARDCv" -> (known after apply) + ~ modified_at = "2024-08-24 00:02:05.606678591 +0000 UTC" -> (known after apply) + ~ modified_by = "s10qrydhDaic9GsWZ6BYpJfSK7wARDCv" -> (known after apply) + ~ version = 2 -> (known after apply) + } -> (known after apply) + ~ commands = [] -> (known after apply) + ~ id = "ffffffff-aaaa-1414-eeee-00000000000" -> (known after apply) + ~ name = "VNETPeerTFTestAZURE" -> "VNETPeerTFTestAZURE2" # forces replacement + ~ provider_config = { # forces replacement + ~ azure_config = { + ~ provider_id = "/subscriptions/ffffffff-aaaa-1414-eeee-00000000000/resourceGroups/rg-ffffffff-aaaa-1414-eeee-00000000000/providers/Microsoft.Network/virtualNetworks/cc-ffffffff-aaaa-1414-eeee-00000000000/virtualNetworkPeerings/cc-ffffffff-aaaa-1414-eeee-00000000000-test-vnet" -> (known after apply) + # (5 unchanged attributes hidden) + } + } + ~ status = { + ~ reasoning = "" -> (known after apply) + ~ state = "complete" -> (known after apply) + } -> (known after apply) + # (4 unchanged attributes hidden) + } + +Plan: 1 to add, 0 to change, 1 to destroy. + +Changes to Outputs: + ~ new_network_peer = { + ~ audit = { + - created_at = "2024-08-24 00:01:23.524305127 +0000 UTC" + - created_by = "s10qrydhDaic9GsWZ6BYpJfSK7wARDCv" + - modified_at = "2024-08-24 00:02:05.606678591 +0000 UTC" + - modified_by = "s10qrydhDaic9GsWZ6BYpJfSK7wARDCv" + - version = 2 + } -> (known after apply) + ~ commands = [] -> (known after apply) + ~ id = "ffffffff-aaaa-1414-eeee-00000000000" -> (known after apply) + ~ name = "VNETPeerTFTestAZURE" -> "VNETPeerTFTestAZURE2" + ~ provider_config = { + ~ azure_config = { + ~ provider_id = "/subscriptions/ffffffff-aaaa-1414-eeee-00000000000/resourceGroups/rg-ffffffff-aaaa-1414-eeee-00000000000/providers/Microsoft.Network/virtualNetworks/cc-ffffffff-aaaa-1414-eeee-00000000000/virtualNetworkPeerings/cc-ffffffff-aaaa-1414-eeee-00000000000-test-vnet" -> (known after apply) + # (5 unchanged attributes hidden) + } + # (2 unchanged attributes hidden) + } + ~ status = { + - reasoning = "" + - state = "complete" + } -> (known after apply) + # (4 unchanged attributes hidden) + } + ~ peer_id = "ffffffff-aaaa-1414-eeee-00000000000" -> (known after apply) + +Do you want to perform these actions? + Terraform will perform the actions described above. + Only 'yes' will be accepted to approve. + + Enter a value: yes + +couchbase-capella_network_peer.new_network_peer: Destroying... [id=ffffffff-aaaa-1414-eeee-00000000000] +couchbase-capella_network_peer.new_network_peer: Still destroying... [id=ffffffff-aaaa-1414-eeee-00000000000, 10s elapsed] +couchbase-capella_network_peer.new_network_peer: Still destroying... [id=ffffffff-aaaa-1414-eeee-00000000000, 20s elapsed] +couchbase-capella_network_peer.new_network_peer: Destruction complete after 26s +couchbase-capella_network_peer.new_network_peer: Creating... +couchbase-capella_network_peer.new_network_peer: Still creating... [10s elapsed] +couchbase-capella_network_peer.new_network_peer: Still creating... [20s elapsed] +couchbase-capella_network_peer.new_network_peer: Still creating... [30s elapsed] +couchbase-capella_network_peer.new_network_peer: Still creating... [40s elapsed] +couchbase-capella_network_peer.new_network_peer: Creation complete after 42s [id=ffffffff-aaaa-1414-eeee-00000000000] + +Apply complete! Resources: 1 added, 0 changed, 1 destroyed. + +Outputs: + +network_peers_list = { + "cluster_id" = "ffffffff-aaaa-1414-eeee-00000000000" + "data" = tolist([ + { + "audit" = { + "created_at" = "2024-08-23 23:30:39.790107885 +0000 UTC" + "created_by" = "s10qrydhDaic9GsWZ6BYpJfSK7wARDCv" + "modified_at" = "2024-08-23 23:35:39.359925093 +0000 UTC" + "modified_by" = "418653cc-a3c5-4943-9ff0-ee4d36a49ca3" + "version" = 6 + } + "id" = "c3319197-22ad-4513-b56d-b5b660c749f5" + "name" = "VNETPeerTFTestAZURE" + "provider_config" = { + "aws_config" = null /* object */ + "azure_config" = { + "cidr" = "10.6.0.0/16" + "provider_id" = "" + "resource_group" = "\"test-rg\"" + "subscription_id" = "\"ffffffff-aaaa-1414-eeee-00000000000\"" + "tenant_id" = "\"ffffffff-aaaa-1414-eeee-00000000000\"" + "vnet_id" = "\"test-vnet\"" + } + "gcp_config" = null /* object */ + } + "status" = { + "reasoning" = "" + "state" = "failed" + } + }, + { + "audit" = { + "created_at" = "2024-08-24 00:01:23.524305127 +0000 UTC" + "created_by" = "s10qrydhDaic9GsWZ6BYpJfSK7wARDCv" + "modified_at" = "2024-08-24 00:02:05.606678591 +0000 UTC" + "modified_by" = "s10qrydhDaic9GsWZ6BYpJfSK7wARDCv" + "version" = 2 + } + "id" = "ffffffff-aaaa-1414-eeee-00000000000" + "name" = "VNETPeerTFTestAZURE" + "provider_config" = { + "aws_config" = null /* object */ + "azure_config" = { + "cidr" = "10.6.0.0/16" + "provider_id" = "/subscriptions/ffffffff-aaaa-1414-eeee-00000000000/resourceGroups/rg-ffffffff-aaaa-1414-eeee-00000000000/providers/Microsoft.Network/virtualNetworks/cc-ffffffff-aaaa-1414-eeee-00000000000/virtualNetworkPeerings/cc-ffffffff-aaaa-1414-eeee-00000000000-test-vnet" + "resource_group" = "test-rg" + "subscription_id" = "ffffffff-aaaa-1414-eeee-00000000000" + "tenant_id" = "ffffffff-aaaa-1414-eeee-00000000000" + "vnet_id" = "test-vnet" + } + "gcp_config" = null /* object */ + } + "status" = { + "reasoning" = "" + "state" = "complete" + } + }, + ]) + "organization_id" = "ffffffff-aaaa-1414-eeee-00000000000" + "project_id" = "ffffffff-aaaa-1414-eeee-00000000000" +} +new_network_peer = { + "audit" = { + "created_at" = "2024-08-24 00:10:56.415670004 +0000 UTC" + "created_by" = "s10qrydhDaic9GsWZ6BYpJfSK7wARDCv" + "modified_at" = "2024-08-24 00:11:37.523742051 +0000 UTC" + "modified_by" = "s10qrydhDaic9GsWZ6BYpJfSK7wARDCv" + "version" = 2 + } + "cluster_id" = "ffffffff-aaaa-1414-eeee-00000000000" + "commands" = toset([]) + "id" = "ffffffff-aaaa-1414-eeee-00000000000" + "name" = "VNETPeerTFTestAZURE2" + "organization_id" = "ffffffff-aaaa-1414-eeee-00000000000" + "project_id" = "ffffffff-aaaa-1414-eeee-00000000000" + "provider_config" = { + "aws_config" = null /* object */ + "azure_config" = { + "cidr" = "10.6.0.0/16" + "provider_id" = "/subscriptions/ffffffff-aaaa-1414-eeee-00000000000/resourceGroups/rg-ffffffff-aaaa-1414-eeee-00000000000/providers/Microsoft.Network/virtualNetworks/cc-ffffffff-aaaa-1414-eeee-00000000000/virtualNetworkPeerings/cc-ffffffff-aaaa-1414-eeee-00000000000-test-vnet" + "resource_group" = "test-rg" + "subscription_id" = "ffffffff-aaaa-1414-eeee-00000000000" + "tenant_id" = "ffffffff-aaaa-1414-eeee-00000000000" + "vnet_id" = "test-vnet" + } + "gcp_config" = null /* object */ + } + "provider_type" = "azure" + "status" = { + "reasoning" = "" + "state" = "complete" + } +} +peer_id = "ffffffff-aaaa-1414-eeee-00000000000" + + +``` + +## DESTROY +### Finally, destroy the resources created by Terraform + +Command: `terraform destroy` + +Sample Output: +``` +$ terraform destroy +╷ +│ Warning: Provider development overrides are in effect +│ +│ The following provider development overrides are set in the CLI configuration: +│ - couchbasecloud/couchbase-capella in /Users/paulomee.de/go/bin +│ +│ The behavior may therefore not match any released version of the provider and applying changes may cause the state to become incompatible with published releases. +╵ +data.couchbase-capella_network_peers.existing_network_peers: Reading... +couchbase-capella_network_peer.new_network_peer: Refreshing state... [id=ffffffff-aaaa-1414-eeee-00000000000] +data.couchbase-capella_network_peers.existing_network_peers: Read complete after 0s + +Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + - destroy + +Terraform will perform the following actions: + + # couchbase-capella_network_peer.new_network_peer will be destroyed + - resource "couchbase-capella_network_peer" "new_network_peer" { + - audit = { + - created_at = "2024-08-24 00:10:56.415670004 +0000 UTC" -> null + - created_by = "s10qrydhDaic9GsWZ6BYpJfSK7wARDCv" -> null + - modified_at = "2024-08-24 00:11:37.523742051 +0000 UTC" -> null + - modified_by = "s10qrydhDaic9GsWZ6BYpJfSK7wARDCv" -> null + - version = 2 -> null + } -> null + - cluster_id = "ffffffff-aaaa-1414-eeee-00000000000" -> null + - commands = [] -> null + - id = "ffffffff-aaaa-1414-eeee-00000000000" -> null + - name = "VNETPeerTFTestAZURE2" -> null + - organization_id = "ffffffff-aaaa-1414-eeee-00000000000" -> null + - project_id = "ffffffff-aaaa-1414-eeee-00000000000" -> null + - provider_config = { + - azure_config = { + - cidr = "10.6.0.0/16" -> null + - provider_id = "/subscriptions/ffffffff-aaaa-1414-eeee-00000000000/resourceGroups/rg-ffffffff-aaaa-1414-eeee-00000000000/providers/Microsoft.Network/virtualNetworks/cc-ffffffff-aaaa-1414-eeee-00000000000/virtualNetworkPeerings/cc-ffffffff-aaaa-1414-eeee-00000000000-test-vnet" -> null + - resource_group = "test-rg" -> null + - subscription_id = "ffffffff-aaaa-1414-eeee-00000000000" -> null + - tenant_id = "ffffffff-aaaa-1414-eeee-00000000000" -> null + - vnet_id = "test-vnet" -> null + } -> null + } -> null + - provider_type = "azure" -> null + - status = { + - reasoning = "" -> null + - state = "complete" -> null + } -> null + } + +Plan: 0 to add, 0 to change, 1 to destroy. + +Changes to Outputs: + - network_peers_list = { + - cluster_id = "ffffffff-aaaa-1414-eeee-00000000000" + - data = [ + - { + - audit = { + - created_at = "2024-08-24 00:10:56.415670004 +0000 UTC" + - created_by = "s10qrydhDaic9GsWZ6BYpJfSK7wARDCv" + - modified_at = "2024-08-24 00:11:37.523742051 +0000 UTC" + - modified_by = "s10qrydhDaic9GsWZ6BYpJfSK7wARDCv" + - version = 2 + } + - id = "ffffffff-aaaa-1414-eeee-00000000000" + - name = "VNETPeerTFTestAZURE2" + - provider_config = { + - aws_config = null + - azure_config = { + - cidr = "10.6.0.0/16" + - provider_id = "/subscriptions/ffffffff-aaaa-1414-eeee-00000000000/resourceGroups/rg-ffffffff-aaaa-1414-eeee-00000000000/providers/Microsoft.Network/virtualNetworks/cc-ffffffff-aaaa-1414-eeee-00000000000/virtualNetworkPeerings/cc-ffffffff-aaaa-1414-eeee-00000000000-test-vnet" + - resource_group = "test-rg" + - subscription_id = "ffffffff-aaaa-1414-eeee-00000000000" + - tenant_id = "ffffffff-aaaa-1414-eeee-00000000000" + - vnet_id = "test-vnet" + } + - gcp_config = null + } + - status = { + - reasoning = "" + - state = "complete" + } + }, + - { + - audit = { + - created_at = "2024-08-23 23:30:39.790107885 +0000 UTC" + - created_by = "s10qrydhDaic9GsWZ6BYpJfSK7wARDCv" + - modified_at = "2024-08-23 23:35:39.359925093 +0000 UTC" + - modified_by = "418653cc-a3c5-4943-9ff0-ee4d36a49ca3" + - version = 6 + } + - id = "c3319197-22ad-4513-b56d-b5b660c749f5" + - name = "VNETPeerTFTestAZURE" + - provider_config = { + - aws_config = null + - azure_config = { + - cidr = "10.6.0.0/16" + - provider_id = "" + - resource_group = "\"test-rg\"" + - subscription_id = "\"ffffffff-aaaa-1414-eeee-00000000000\"" + - tenant_id = "\"ffffffff-aaaa-1414-eeee-00000000000\"" + - vnet_id = "\"test-vnet\"" + } + - gcp_config = null + } + - status = { + - reasoning = "" + - state = "failed" + } + }, + ] + - organization_id = "ffffffff-aaaa-1414-eeee-00000000000" + - project_id = "ffffffff-aaaa-1414-eeee-00000000000" + } -> null + - new_network_peer = { + - audit = { + - created_at = "2024-08-24 00:10:56.415670004 +0000 UTC" + - created_by = "s10qrydhDaic9GsWZ6BYpJfSK7wARDCv" + - modified_at = "2024-08-24 00:11:37.523742051 +0000 UTC" + - modified_by = "s10qrydhDaic9GsWZ6BYpJfSK7wARDCv" + - version = 2 + } + - cluster_id = "ffffffff-aaaa-1414-eeee-00000000000" + - commands = [] + - id = "ffffffff-aaaa-1414-eeee-00000000000" + - name = "VNETPeerTFTestAZURE2" + - organization_id = "ffffffff-aaaa-1414-eeee-00000000000" + - project_id = "ffffffff-aaaa-1414-eeee-00000000000" + - provider_config = { + - aws_config = null + - azure_config = { + - cidr = "10.6.0.0/16" + - provider_id = "/subscriptions/ffffffff-aaaa-1414-eeee-00000000000/resourceGroups/rg-ffffffff-aaaa-1414-eeee-00000000000/providers/Microsoft.Network/virtualNetworks/cc-ffffffff-aaaa-1414-eeee-00000000000/virtualNetworkPeerings/cc-ffffffff-aaaa-1414-eeee-00000000000-test-vnet" + - resource_group = "test-rg" + - subscription_id = "ffffffff-aaaa-1414-eeee-00000000000" + - tenant_id = "ffffffff-aaaa-1414-eeee-00000000000" + - vnet_id = "test-vnet" + } + - gcp_config = null + } + - provider_type = "azure" + - status = { + - reasoning = "" + - state = "complete" + } + } -> null + - peer_id = "ffffffff-aaaa-1414-eeee-00000000000" -> null + +Do you really want to destroy all resources? + Terraform will destroy all your managed infrastructure, as shown above. + There is no undo. Only 'yes' will be accepted to confirm. + + Enter a value: yes + +couchbase-capella_network_peer.new_network_peer: Destroying... [id=ffffffff-aaaa-1414-eeee-00000000000] +couchbase-capella_network_peer.new_network_peer: Still destroying... [id=ffffffff-aaaa-1414-eeee-00000000000, 10s elapsed] +couchbase-capella_network_peer.new_network_peer: Still destroying... [id=ffffffff-aaaa-1414-eeee-00000000000, 20s elapsed] +couchbase-capella_network_peer.new_network_peer: Destruction complete after 26s + +Destroy complete! Resources: 1 destroyed. + + ``` diff --git a/examples/network_peer_command_azure/README.md b/examples/network_peer_command_azure/README.md index 503fa1da..47ca53fa 100644 --- a/examples/network_peer_command_azure/README.md +++ b/examples/network_peer_command_azure/README.md @@ -1 +1,69 @@ -#TODO \ No newline at end of file +# Capella Azure VNET Peering CLI Command Example + +This example shows how to retrieve the Azure role assignment command to be run in the Azure CLI that is used to configure a network peer. + +To run, configure your Couchbase Capella provider as described in README in the root of this project. + +# Example Walkthrough + +In this example, we are going to do the following. + +1. GET: Display the Azure network peer cli command as stated in the `get_network_peer_command.tf` file. + +## GET + +Command: `terraform apply` + +Sample Output: +``` + terraform apply +╷ +│ Warning: Provider development overrides are in effect +│ +│ The following provider development overrides are set in the CLI configuration: +│ - couchbasecloud/couchbase-capella in /Users/paulomee.de/go/bin +│ +│ The behavior may therefore not match any released version of the provider and applying changes may cause the state to become incompatible with published releases. +╵ +data.couchbase-capella_azure_network_peer_command.azure_network_peer_command: Reading... +data.couchbase-capella_azure_network_peer_command.azure_network_peer_command: Read complete after 0s + +Changes to Outputs: + + azure_network_peer_command = { + + cluster_id = "ffffffff-aaaa-1414-eeee-000000000000" + + command = "az role assignment create --assignee-object-id ffffffff-aaaa-1414-eeee-000000000000 --role \"Network Contributor\" --scope /subscriptions/ffffffff-aaaa-1414-eeee-000000000000/resourceGroups/test_rg/providers/Microsoft.Network/VirtualNetworks/test_vnet --assignee-principal-type ServicePrincipal" + + organization_id = "ffffffff-aaaa-1414-eeee-000000000000" + + project_id = "ffffffff-aaaa-1414-eeee-000000000000" + + resource_group = "test_rg" + + subscription_id = "ffffffff-aaaa-1414-eeee-000000000000" + + tenant_id = "ffffffff-aaaa-1414-eeee-000000000000" + + vnet_id = "test_vnet" + + vnet_peering_service_principal = "ffffffff-aaaa-1414-eeee-000000000000" + } + +You can apply this plan to save these new output values to the Terraform state, without changing any real infrastructure. + +Do you want to perform these actions? + Terraform will perform the actions described above. + Only 'yes' will be accepted to approve. + + Enter a value: yes + + +Apply complete! Resources: 0 added, 0 changed, 0 destroyed. + +Outputs: + +azure_network_peer_command = { + "cluster_id" = "ffffffff-aaaa-1414-eeee-000000000000" + "command" = "az role assignment create --assignee-object-id ffffffff-aaaa-1414-eeee-000000000000 --role \"Network Contributor\" --scope /subscriptions/ffffffff-aaaa-1414-eeee-000000000000/resourceGroups/test_rg/providers/Microsoft.Network/VirtualNetworks/test_vnet --assignee-principal-type ServicePrincipal" + "organization_id" = "ffffffff-aaaa-1414-eeee-000000000000" + "project_id" = "ffffffff-aaaa-1414-eeee-000000000000" + "resource_group" = "test_rg" + "subscription_id" = "ffffffff-aaaa-1414-eeee-000000000000" + "tenant_id" = "ffffffff-aaaa-1414-eeee-000000000000" + "vnet_id" = "test_vnet" + "vnet_peering_service_principal" = "ffffffff-aaaa-1414-eeee-000000000000" +} + +``` \ No newline at end of file From d343ce5617200fdf2972796bbe71185e5274a2bb Mon Sep 17 00:00:00 2001 From: PaulomeeCb Date: Fri, 23 Aug 2024 17:22:33 -0700 Subject: [PATCH 12/23] Updating vnet_id example --- examples/network_peer/terraform.template.tfvars | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/network_peer/terraform.template.tfvars b/examples/network_peer/terraform.template.tfvars index c6ecf48a..27aadfe0 100644 --- a/examples/network_peer/terraform.template.tfvars +++ b/examples/network_peer/terraform.template.tfvars @@ -38,5 +38,5 @@ aws_config = { # subscription_id = "ffffffff-aaaa-1414-eeee-000000000000" # cidr = "10.0.0.0/16" # resource_group = "test-rg" -# vnet_id = "ffffffff-aaaa-1414-eeee-000000000000" +# vnet_id = "test-vnet" # } \ No newline at end of file From c1d8bc50d81b180151b92f93df78bdb8e5c34ae0 Mon Sep 17 00:00:00 2001 From: PaulomeeCb Date: Fri, 23 Aug 2024 17:32:24 -0700 Subject: [PATCH 13/23] Formatting --- examples/network_peer/create_network_peer.tf | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/examples/network_peer/create_network_peer.tf b/examples/network_peer/create_network_peer.tf index 31608d32..7a29414f 100644 --- a/examples/network_peer/create_network_peer.tf +++ b/examples/network_peer/create_network_peer.tf @@ -32,10 +32,10 @@ resource "couchbase-capella_network_peer" "new_network_peer" { # Example Azure Config for creating network peer on Azure. Use this instead of aws_config above if you want to create a network peer for Azure. -# azure_config = { -# tenant_id = var.azure_config.tenant_id -# resource_group = var.azure_config.resource_group -# subscription_id = var.azure_config.subscription_id -# cidr = var.azure_config.cidr -# vnet_id = var.azure_config.vnet_id -# } \ No newline at end of file +# azure_config = { +# tenant_id = var.azure_config.tenant_id +# resource_group = var.azure_config.resource_group +# subscription_id = var.azure_config.subscription_id +# cidr = var.azure_config.cidr +# vnet_id = var.azure_config.vnet_id +# } \ No newline at end of file From 21a1fa2582eb48f9e5db51cd5a8fc5ccb880ba3d Mon Sep 17 00:00:00 2001 From: PaulomeeCb Date: Wed, 28 Aug 2024 17:38:16 -0700 Subject: [PATCH 14/23] Adding condition to handle empty provider_config --- internal/errors/errors.go | 3 +++ internal/resources/network_peer.go | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/internal/errors/errors.go b/internal/errors/errors.go index 7747f4f9..2698fd81 100644 --- a/internal/errors/errors.go +++ b/internal/errors/errors.go @@ -207,4 +207,7 @@ var ( // ErrConvertingProviderConfig is returned when terraform fails to convert a network peer provider config. ErrConvertingProviderConfig = errors.New("failed to convert network peer provider config, please contact Couchbase Capella Support") + + // ErrProviderConfigCannotBeEmpty is returned when the provider_config was required for a request but was empty. + ErrProviderConfigCannotBeEmpty = errors.New("provider_config cannot be empty, it should be populated with one of- aws_config, gcp_config or azure_config. Please contact Couchbase Capella Support") ) diff --git a/internal/resources/network_peer.go b/internal/resources/network_peer.go index b12b9cb7..33774dc1 100644 --- a/internal/resources/network_peer.go +++ b/internal/resources/network_peer.go @@ -126,6 +126,12 @@ func (n *NetworkPeer) Create(ctx context.Context, req resource.CreateRequest, re networkPeerRequest.ProviderConfig = providerConfigJSON plan.ProviderConfig.AWSConfig = nil plan.ProviderConfig.GCPConfig = nil + } else { + resp.Diagnostics.AddError( + "Provider Config cannot be empty", + errors.ErrProviderConfigCannotBeEmpty.Error(), + ) + return } var ( From 37437994c0efc0ce263740afaa600224f45a9017 Mon Sep 17 00:00:00 2001 From: PaulomeeCb Date: Mon, 9 Sep 2024 15:56:58 -0700 Subject: [PATCH 15/23] Adding switch case --- internal/resources/network_peer.go | 77 +++++++++++++++++++++++++++--- 1 file changed, 71 insertions(+), 6 deletions(-) diff --git a/internal/resources/network_peer.go b/internal/resources/network_peer.go index 33774dc1..74737b2a 100644 --- a/internal/resources/network_peer.go +++ b/internal/resources/network_peer.go @@ -67,7 +67,8 @@ func (n *NetworkPeer) Create(ctx context.Context, req resource.CreateRequest, re ProviderType: plan.ProviderType.ValueString(), } - if plan.ProviderConfig.AWSConfig != nil { + switch { + case plan.ProviderConfig.AWSConfig != nil: awsConfigForJSON := network_peer_api.AWSConfigData{ AccountId: plan.ProviderConfig.AWSConfig.AccountId.ValueString(), Cidr: plan.ProviderConfig.AWSConfig.Cidr.ValueString(), @@ -87,8 +88,7 @@ func (n *NetworkPeer) Create(ctx context.Context, req resource.CreateRequest, re networkPeerRequest.ProviderConfig = providerConfigJSON plan.ProviderConfig.GCPConfig = nil plan.ProviderConfig.AzureConfig = nil - - } else if plan.ProviderConfig.GCPConfig != nil { + case plan.ProviderConfig.GCPConfig != nil: gcpConfigJSON := network_peer_api.GCPConfigData{ NetworkName: plan.ProviderConfig.GCPConfig.NetworkName.ValueString(), ProjectId: plan.ProviderConfig.GCPConfig.ProjectId.ValueString(), @@ -106,8 +106,7 @@ func (n *NetworkPeer) Create(ctx context.Context, req resource.CreateRequest, re networkPeerRequest.ProviderConfig = providerConfigJSON plan.ProviderConfig.AWSConfig = nil plan.ProviderConfig.AzureConfig = nil - - } else if plan.ProviderConfig.AzureConfig != nil { + case plan.ProviderConfig.AzureConfig != nil: azureConfigJSON := network_peer_api.AzureConfigData{ AzureTenantId: plan.ProviderConfig.AzureConfig.AzureTenantId.ValueString(), ResourceGroup: plan.ProviderConfig.AzureConfig.ResourceGroup.ValueString(), @@ -126,13 +125,79 @@ func (n *NetworkPeer) Create(ctx context.Context, req resource.CreateRequest, re networkPeerRequest.ProviderConfig = providerConfigJSON plan.ProviderConfig.AWSConfig = nil plan.ProviderConfig.GCPConfig = nil - } else { + default: resp.Diagnostics.AddError( "Provider Config cannot be empty", errors.ErrProviderConfigCannotBeEmpty.Error(), ) return } + //if plan.ProviderConfig.AWSConfig != nil { + // awsConfigForJSON := network_peer_api.AWSConfigData{ + // AccountId: plan.ProviderConfig.AWSConfig.AccountId.ValueString(), + // Cidr: plan.ProviderConfig.AWSConfig.Cidr.ValueString(), + // Region: plan.ProviderConfig.AWSConfig.Region.ValueString(), + // VpcId: plan.ProviderConfig.AWSConfig.VpcId.ValueString(), + // } + // + // providerConfigJSON, err := json.Marshal(awsConfigForJSON) + // if err != nil { + // resp.Diagnostics.AddError( + // "Error creating network peer for AWS", + // errors.ErrConvertingProviderConfig.Error(), + // ) + // return + // } + // + // networkPeerRequest.ProviderConfig = providerConfigJSON + // plan.ProviderConfig.GCPConfig = nil + // plan.ProviderConfig.AzureConfig = nil + + //} else if plan.ProviderConfig.GCPConfig != nil { + // gcpConfigJSON := network_peer_api.GCPConfigData{ + // NetworkName: plan.ProviderConfig.GCPConfig.NetworkName.ValueString(), + // ProjectId: plan.ProviderConfig.GCPConfig.ProjectId.ValueString(), + // Cidr: plan.ProviderConfig.GCPConfig.Cidr.ValueString(), + // ServiceAccount: plan.ProviderConfig.GCPConfig.ServiceAccount.ValueString(), + // } + // providerConfigJSON, err := json.Marshal(gcpConfigJSON) + // if err != nil { + // resp.Diagnostics.AddError( + // "Error creating network peer for GCP", + // errors.ErrConvertingProviderConfig.Error(), + // ) + // return + // } + // networkPeerRequest.ProviderConfig = providerConfigJSON + // plan.ProviderConfig.AWSConfig = nil + // plan.ProviderConfig.AzureConfig = nil + + //} else if plan.ProviderConfig.AzureConfig != nil { + // azureConfigJSON := network_peer_api.AzureConfigData{ + // AzureTenantId: plan.ProviderConfig.AzureConfig.AzureTenantId.ValueString(), + // ResourceGroup: plan.ProviderConfig.AzureConfig.ResourceGroup.ValueString(), + // SubscriptionId: plan.ProviderConfig.AzureConfig.SubscriptionId.ValueString(), + // VnetId: plan.ProviderConfig.AzureConfig.VnetId.ValueString(), + // Cidr: plan.ProviderConfig.AzureConfig.Cidr.ValueString(), + // } + // providerConfigJSON, err := json.Marshal(azureConfigJSON) + // if err != nil { + // resp.Diagnostics.AddError( + // "Error creating network peer for Azure", + // errors.ErrConvertingProviderConfig.Error(), + // ) + // return + // } + // networkPeerRequest.ProviderConfig = providerConfigJSON + // plan.ProviderConfig.AWSConfig = nil + // plan.ProviderConfig.GCPConfig = nil + //} else { + // resp.Diagnostics.AddError( + // "Provider Config cannot be empty", + // errors.ErrProviderConfigCannotBeEmpty.Error(), + // ) + // return + //} var ( organizationId = plan.OrganizationId.ValueString() From a7c3231cae3c3fd22feead797579f2792ffc1ad8 Mon Sep 17 00:00:00 2001 From: PaulomeeCb Date: Tue, 10 Sep 2024 12:24:34 -0700 Subject: [PATCH 16/23] Refactoring code --- internal/resources/network_peer.go | 160 ++++++++++++----------------- 1 file changed, 64 insertions(+), 96 deletions(-) diff --git a/internal/resources/network_peer.go b/internal/resources/network_peer.go index 74737b2a..ad35d2da 100644 --- a/internal/resources/network_peer.go +++ b/internal/resources/network_peer.go @@ -69,14 +69,7 @@ func (n *NetworkPeer) Create(ctx context.Context, req resource.CreateRequest, re switch { case plan.ProviderConfig.AWSConfig != nil: - awsConfigForJSON := network_peer_api.AWSConfigData{ - AccountId: plan.ProviderConfig.AWSConfig.AccountId.ValueString(), - Cidr: plan.ProviderConfig.AWSConfig.Cidr.ValueString(), - Region: plan.ProviderConfig.AWSConfig.Region.ValueString(), - VpcId: plan.ProviderConfig.AWSConfig.VpcId.ValueString(), - } - - providerConfigJSON, err := json.Marshal(awsConfigForJSON) + providerConfigJSON, err := createAWSProviderConfig(plan) if err != nil { resp.Diagnostics.AddError( "Error creating network peer for AWS", @@ -84,18 +77,9 @@ func (n *NetworkPeer) Create(ctx context.Context, req resource.CreateRequest, re ) return } - networkPeerRequest.ProviderConfig = providerConfigJSON - plan.ProviderConfig.GCPConfig = nil - plan.ProviderConfig.AzureConfig = nil case plan.ProviderConfig.GCPConfig != nil: - gcpConfigJSON := network_peer_api.GCPConfigData{ - NetworkName: plan.ProviderConfig.GCPConfig.NetworkName.ValueString(), - ProjectId: plan.ProviderConfig.GCPConfig.ProjectId.ValueString(), - Cidr: plan.ProviderConfig.GCPConfig.Cidr.ValueString(), - ServiceAccount: plan.ProviderConfig.GCPConfig.ServiceAccount.ValueString(), - } - providerConfigJSON, err := json.Marshal(gcpConfigJSON) + providerConfigJSON, err := createGCPProviderConfig(plan) if err != nil { resp.Diagnostics.AddError( "Error creating network peer for GCP", @@ -104,17 +88,8 @@ func (n *NetworkPeer) Create(ctx context.Context, req resource.CreateRequest, re return } networkPeerRequest.ProviderConfig = providerConfigJSON - plan.ProviderConfig.AWSConfig = nil - plan.ProviderConfig.AzureConfig = nil case plan.ProviderConfig.AzureConfig != nil: - azureConfigJSON := network_peer_api.AzureConfigData{ - AzureTenantId: plan.ProviderConfig.AzureConfig.AzureTenantId.ValueString(), - ResourceGroup: plan.ProviderConfig.AzureConfig.ResourceGroup.ValueString(), - SubscriptionId: plan.ProviderConfig.AzureConfig.SubscriptionId.ValueString(), - VnetId: plan.ProviderConfig.AzureConfig.VnetId.ValueString(), - Cidr: plan.ProviderConfig.AzureConfig.Cidr.ValueString(), - } - providerConfigJSON, err := json.Marshal(azureConfigJSON) + providerConfigJSON, err := createAzureProviderConfig(plan) if err != nil { resp.Diagnostics.AddError( "Error creating network peer for Azure", @@ -123,8 +98,6 @@ func (n *NetworkPeer) Create(ctx context.Context, req resource.CreateRequest, re return } networkPeerRequest.ProviderConfig = providerConfigJSON - plan.ProviderConfig.AWSConfig = nil - plan.ProviderConfig.GCPConfig = nil default: resp.Diagnostics.AddError( "Provider Config cannot be empty", @@ -132,72 +105,6 @@ func (n *NetworkPeer) Create(ctx context.Context, req resource.CreateRequest, re ) return } - //if plan.ProviderConfig.AWSConfig != nil { - // awsConfigForJSON := network_peer_api.AWSConfigData{ - // AccountId: plan.ProviderConfig.AWSConfig.AccountId.ValueString(), - // Cidr: plan.ProviderConfig.AWSConfig.Cidr.ValueString(), - // Region: plan.ProviderConfig.AWSConfig.Region.ValueString(), - // VpcId: plan.ProviderConfig.AWSConfig.VpcId.ValueString(), - // } - // - // providerConfigJSON, err := json.Marshal(awsConfigForJSON) - // if err != nil { - // resp.Diagnostics.AddError( - // "Error creating network peer for AWS", - // errors.ErrConvertingProviderConfig.Error(), - // ) - // return - // } - // - // networkPeerRequest.ProviderConfig = providerConfigJSON - // plan.ProviderConfig.GCPConfig = nil - // plan.ProviderConfig.AzureConfig = nil - - //} else if plan.ProviderConfig.GCPConfig != nil { - // gcpConfigJSON := network_peer_api.GCPConfigData{ - // NetworkName: plan.ProviderConfig.GCPConfig.NetworkName.ValueString(), - // ProjectId: plan.ProviderConfig.GCPConfig.ProjectId.ValueString(), - // Cidr: plan.ProviderConfig.GCPConfig.Cidr.ValueString(), - // ServiceAccount: plan.ProviderConfig.GCPConfig.ServiceAccount.ValueString(), - // } - // providerConfigJSON, err := json.Marshal(gcpConfigJSON) - // if err != nil { - // resp.Diagnostics.AddError( - // "Error creating network peer for GCP", - // errors.ErrConvertingProviderConfig.Error(), - // ) - // return - // } - // networkPeerRequest.ProviderConfig = providerConfigJSON - // plan.ProviderConfig.AWSConfig = nil - // plan.ProviderConfig.AzureConfig = nil - - //} else if plan.ProviderConfig.AzureConfig != nil { - // azureConfigJSON := network_peer_api.AzureConfigData{ - // AzureTenantId: plan.ProviderConfig.AzureConfig.AzureTenantId.ValueString(), - // ResourceGroup: plan.ProviderConfig.AzureConfig.ResourceGroup.ValueString(), - // SubscriptionId: plan.ProviderConfig.AzureConfig.SubscriptionId.ValueString(), - // VnetId: plan.ProviderConfig.AzureConfig.VnetId.ValueString(), - // Cidr: plan.ProviderConfig.AzureConfig.Cidr.ValueString(), - // } - // providerConfigJSON, err := json.Marshal(azureConfigJSON) - // if err != nil { - // resp.Diagnostics.AddError( - // "Error creating network peer for Azure", - // errors.ErrConvertingProviderConfig.Error(), - // ) - // return - // } - // networkPeerRequest.ProviderConfig = providerConfigJSON - // plan.ProviderConfig.AWSConfig = nil - // plan.ProviderConfig.GCPConfig = nil - //} else { - // resp.Diagnostics.AddError( - // "Provider Config cannot be empty", - // errors.ErrProviderConfigCannotBeEmpty.Error(), - // ) - // return - //} var ( organizationId = plan.OrganizationId.ValueString() @@ -264,6 +171,67 @@ func (n *NetworkPeer) Create(ctx context.Context, req resource.CreateRequest, re } } +// Extracted function to handle AWS configuration +func createAWSProviderConfig(plan providerschema.NetworkPeer) ([]byte, error) { + awsConfigForJSON := network_peer_api.AWSConfigData{ + AccountId: plan.ProviderConfig.AWSConfig.AccountId.ValueString(), + Cidr: plan.ProviderConfig.AWSConfig.Cidr.ValueString(), + Region: plan.ProviderConfig.AWSConfig.Region.ValueString(), + VpcId: plan.ProviderConfig.AWSConfig.VpcId.ValueString(), + } + + providerConfigJSON, err := json.Marshal(awsConfigForJSON) + if err != nil { + return nil, err + } + + plan.ProviderConfig.GCPConfig = nil + plan.ProviderConfig.AzureConfig = nil + + return providerConfigJSON, nil +} + +// Extracted function to handle GCP configuration +func createGCPProviderConfig(plan providerschema.NetworkPeer) ([]byte, error) { + gcpConfigJSON := network_peer_api.GCPConfigData{ + NetworkName: plan.ProviderConfig.GCPConfig.NetworkName.ValueString(), + ProjectId: plan.ProviderConfig.GCPConfig.ProjectId.ValueString(), + Cidr: plan.ProviderConfig.GCPConfig.Cidr.ValueString(), + ServiceAccount: plan.ProviderConfig.GCPConfig.ServiceAccount.ValueString(), + } + + providerConfigJSON, err := json.Marshal(gcpConfigJSON) + if err != nil { + return nil, err + } + + plan.ProviderConfig.AWSConfig = nil + plan.ProviderConfig.AzureConfig = nil + + return providerConfigJSON, nil +} + +// Extracted function to handle Azure configuration +func createAzureProviderConfig(plan providerschema.NetworkPeer) ([]byte, error) { + azureConfigJSON := network_peer_api.AzureConfigData{ + AzureTenantId: plan.ProviderConfig.AzureConfig.AzureTenantId.ValueString(), + ResourceGroup: plan.ProviderConfig.AzureConfig.ResourceGroup.ValueString(), + SubscriptionId: plan.ProviderConfig.AzureConfig.SubscriptionId.ValueString(), + VnetId: plan.ProviderConfig.AzureConfig.VnetId.ValueString(), + Cidr: plan.ProviderConfig.AzureConfig.Cidr.ValueString(), + } + + providerConfigJSON, err := json.Marshal(azureConfigJSON) + if err != nil { + return nil, err + } + + plan.ProviderConfig.AWSConfig = nil + plan.ProviderConfig.GCPConfig = nil + + return providerConfigJSON, nil +} + // Read reads the NetworkPeer information. func (n *NetworkPeer) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { var state providerschema.NetworkPeer From 523b32dd0adae2c0fc3698b3c51e5ec0c72adc1a Mon Sep 17 00:00:00 2001 From: PaulomeeCb Date: Tue, 10 Sep 2024 12:27:36 -0700 Subject: [PATCH 17/23] godocs updating --- internal/resources/network_peer.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/resources/network_peer.go b/internal/resources/network_peer.go index ad35d2da..868c49cf 100644 --- a/internal/resources/network_peer.go +++ b/internal/resources/network_peer.go @@ -171,7 +171,7 @@ func (n *NetworkPeer) Create(ctx context.Context, req resource.CreateRequest, re } } -// Extracted function to handle AWS configuration +// createAWSProviderConfig is the function to handle AWS configuration func createAWSProviderConfig(plan providerschema.NetworkPeer) ([]byte, error) { awsConfigForJSON := network_peer_api.AWSConfigData{ AccountId: plan.ProviderConfig.AWSConfig.AccountId.ValueString(), @@ -191,7 +191,7 @@ func createAWSProviderConfig(plan providerschema.NetworkPeer) ([]byte, error) { return providerConfigJSON, nil } -// Extracted function to handle GCP configuration +// createGCPProviderConfig is the function to handle GCP configuration func createGCPProviderConfig(plan providerschema.NetworkPeer) ([]byte, error) { gcpConfigJSON := network_peer_api.GCPConfigData{ NetworkName: plan.ProviderConfig.GCPConfig.NetworkName.ValueString(), @@ -211,7 +211,7 @@ func createGCPProviderConfig(plan providerschema.NetworkPeer) ([]byte, error) { return providerConfigJSON, nil } -// Extracted function to handle Azure configuration +// createAzureProviderConfig is the function to handle Azure configuration func createAzureProviderConfig(plan providerschema.NetworkPeer) ([]byte, error) { azureConfigJSON := network_peer_api.AzureConfigData{ AzureTenantId: plan.ProviderConfig.AzureConfig.AzureTenantId.ValueString(), From 4e0df96626bc840152db5c9c90490e4200537dba Mon Sep 17 00:00:00 2001 From: PaulomeeCb Date: Tue, 10 Sep 2024 12:32:53 -0700 Subject: [PATCH 18/23] Comment lint error resolve --- internal/resources/network_peer.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/resources/network_peer.go b/internal/resources/network_peer.go index 868c49cf..89f47fe6 100644 --- a/internal/resources/network_peer.go +++ b/internal/resources/network_peer.go @@ -171,7 +171,7 @@ func (n *NetworkPeer) Create(ctx context.Context, req resource.CreateRequest, re } } -// createAWSProviderConfig is the function to handle AWS configuration +// createAWSProviderConfig is the function to handle AWS configuration. func createAWSProviderConfig(plan providerschema.NetworkPeer) ([]byte, error) { awsConfigForJSON := network_peer_api.AWSConfigData{ AccountId: plan.ProviderConfig.AWSConfig.AccountId.ValueString(), @@ -191,7 +191,7 @@ func createAWSProviderConfig(plan providerschema.NetworkPeer) ([]byte, error) { return providerConfigJSON, nil } -// createGCPProviderConfig is the function to handle GCP configuration +// createGCPProviderConfig is the function to handle GCP configuration. func createGCPProviderConfig(plan providerschema.NetworkPeer) ([]byte, error) { gcpConfigJSON := network_peer_api.GCPConfigData{ NetworkName: plan.ProviderConfig.GCPConfig.NetworkName.ValueString(), @@ -211,7 +211,7 @@ func createGCPProviderConfig(plan providerschema.NetworkPeer) ([]byte, error) { return providerConfigJSON, nil } -// createAzureProviderConfig is the function to handle Azure configuration +// createAzureProviderConfig is the function to handle Azure configuration. func createAzureProviderConfig(plan providerschema.NetworkPeer) ([]byte, error) { azureConfigJSON := network_peer_api.AzureConfigData{ AzureTenantId: plan.ProviderConfig.AzureConfig.AzureTenantId.ValueString(), From c6a625777f433081446b97ad7b289b93b5d690ea Mon Sep 17 00:00:00 2001 From: Paulomee De <124640240+PaulomeeCb@users.noreply.github.com> Date: Thu, 12 Sep 2024 17:20:50 -0700 Subject: [PATCH 19/23] Update examples/network_peer/README.md Co-authored-by: aniket-Kumar-c <115682403+aniket-Kumar-c@users.noreply.github.com> --- examples/network_peer/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/network_peer/README.md b/examples/network_peer/README.md index 53d942a0..0a9c74f2 100644 --- a/examples/network_peer/README.md +++ b/examples/network_peer/README.md @@ -1395,7 +1395,7 @@ $ terraform plan │ Warning: Provider development overrides are in effect │ │ The following provider development overrides are set in the CLI configuration: -│ - couchbasecloud/couchbase-capella in /Users/paulomee.de/go/bin +│ - couchbasecloud/couchbase-capella in /Users/$USER/workspace//go/bin │ │ The behavior may therefore not match any released version of the provider and applying changes may cause the state to become incompatible with published releases. ╵ From 1ac987c9baa2447e465ceac3520471374297b06f Mon Sep 17 00:00:00 2001 From: PaulomeeCb Date: Mon, 16 Sep 2024 15:45:58 -0700 Subject: [PATCH 20/23] Removing name and apikey as per review comments --- examples/network_peer/README.md | 52 +++++++++---------- examples/network_peer_command_azure/README.md | 2 +- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/examples/network_peer/README.md b/examples/network_peer/README.md index 0a9c74f2..f5fd1cab 100644 --- a/examples/network_peer/README.md +++ b/examples/network_peer/README.md @@ -1439,7 +1439,7 @@ Changes to Outputs: + { + audit = { + created_at = "2024-08-23 23:30:39.790107885 +0000 UTC" - + created_by = "s10qrydhDaic9GsWZ6BYpJfSK7wARDCv" + + created_by = "sample_apikey" + modified_at = "2024-08-23 23:35:39.359925093 +0000 UTC" + modified_by = "ffffffff-aaaa-1414-eeee-00000000000" + version = 6 @@ -1509,7 +1509,7 @@ $ terraform apply │ Warning: Provider development overrides are in effect │ │ The following provider development overrides are set in the CLI configuration: -│ - couchbasecloud/couchbase-capella in /Users/paulomee.de/go/bin +│ - couchbasecloud/couchbase-capella in /Users/$USER/go/bin │ │ The behavior may therefore not match any released version of the provider and applying changes may cause the state to become incompatible with published releases. ╵ @@ -1553,7 +1553,7 @@ Changes to Outputs: + { + audit = { + created_at = "2024-08-23 23:30:39.790107885 +0000 UTC" - + created_by = "s10qrydhDaic9GsWZ6BYpJfSK7wARDCv" + + created_by = "sample_apikey" + modified_at = "2024-08-23 23:35:39.359925093 +0000 UTC" + modified_by = "ffffffff-aaaa-1414-eeee-00000000000" + version = 6 @@ -1629,7 +1629,7 @@ network_peers_list = { { "audit" = { "created_at" = "2024-08-23 23:30:39.790107885 +0000 UTC" - "created_by" = "s10qrydhDaic9GsWZ6BYpJfSK7wARDCv" + "created_by" = "sample_apikey" "modified_at" = "2024-08-23 23:35:39.359925093 +0000 UTC" "modified_by" = "ffffffff-aaaa-1414-eeee-00000000000" "version" = 6 @@ -1660,9 +1660,9 @@ network_peers_list = { new_network_peer = { "audit" = { "created_at" = "2024-08-24 00:01:23.524305127 +0000 UTC" - "created_by" = "s10qrydhDaic9GsWZ6BYpJfSK7wARDCv" + "created_by" = "sample_apikey" "modified_at" = "2024-08-24 00:02:05.606678591 +0000 UTC" - "modified_by" = "s10qrydhDaic9GsWZ6BYpJfSK7wARDCv" + "modified_by" = "sample_apikey" "version" = 2 } "cluster_id" = "ffffffff-aaaa-1414-eeee-00000000000" @@ -1702,9 +1702,9 @@ $ terraform output new_network_peer { "audit" = { "created_at" = "2024-08-24 00:01:23.524305127 +0000 UTC" - "created_by" = "s10qrydhDaic9GsWZ6BYpJfSK7wARDCv" + "created_by" = "sample_apikey" "modified_at" = "2024-08-24 00:02:05.606678591 +0000 UTC" - "modified_by" = "s10qrydhDaic9GsWZ6BYpJfSK7wARDCv" + "modified_by" = "sample_apikey" "version" = 2 } "cluster_id" = "ffffffff-aaaa-1414-eeee-00000000000" @@ -1831,7 +1831,7 @@ $ terraform apply │ Warning: Provider development overrides are in effect │ │ The following provider development overrides are set in the CLI configuration: -│ - couchbasecloud/couchbase-capella in /Users/paulomee.de/go/bin +│ - couchbasecloud/couchbase-capella in /Users/$USER/go/bin │ │ The behavior may therefore not match any released version of the provider and applying changes may cause the state to become incompatible with published releases. ╵ @@ -1848,9 +1848,9 @@ Terraform will perform the following actions: -/+ resource "couchbase-capella_network_peer" "new_network_peer" { ~ audit = { ~ created_at = "2024-08-24 00:01:23.524305127 +0000 UTC" -> (known after apply) - ~ created_by = "s10qrydhDaic9GsWZ6BYpJfSK7wARDCv" -> (known after apply) + ~ created_by = "sample_apikey" -> (known after apply) ~ modified_at = "2024-08-24 00:02:05.606678591 +0000 UTC" -> (known after apply) - ~ modified_by = "s10qrydhDaic9GsWZ6BYpJfSK7wARDCv" -> (known after apply) + ~ modified_by = "sample_apikey" -> (known after apply) ~ version = 2 -> (known after apply) } -> (known after apply) ~ commands = [] -> (known after apply) @@ -1875,9 +1875,9 @@ Changes to Outputs: ~ new_network_peer = { ~ audit = { - created_at = "2024-08-24 00:01:23.524305127 +0000 UTC" - - created_by = "s10qrydhDaic9GsWZ6BYpJfSK7wARDCv" + - created_by = "sample_apikey" - modified_at = "2024-08-24 00:02:05.606678591 +0000 UTC" - - modified_by = "s10qrydhDaic9GsWZ6BYpJfSK7wARDCv" + - modified_by = "sample_apikey" - version = 2 } -> (known after apply) ~ commands = [] -> (known after apply) @@ -1925,7 +1925,7 @@ network_peers_list = { { "audit" = { "created_at" = "2024-08-23 23:30:39.790107885 +0000 UTC" - "created_by" = "s10qrydhDaic9GsWZ6BYpJfSK7wARDCv" + "created_by" = "sample_apikey" "modified_at" = "2024-08-23 23:35:39.359925093 +0000 UTC" "modified_by" = "418653cc-a3c5-4943-9ff0-ee4d36a49ca3" "version" = 6 @@ -1952,9 +1952,9 @@ network_peers_list = { { "audit" = { "created_at" = "2024-08-24 00:01:23.524305127 +0000 UTC" - "created_by" = "s10qrydhDaic9GsWZ6BYpJfSK7wARDCv" + "created_by" = "sample_apikey" "modified_at" = "2024-08-24 00:02:05.606678591 +0000 UTC" - "modified_by" = "s10qrydhDaic9GsWZ6BYpJfSK7wARDCv" + "modified_by" = "sample_apikey" "version" = 2 } "id" = "ffffffff-aaaa-1414-eeee-00000000000" @@ -1983,9 +1983,9 @@ network_peers_list = { new_network_peer = { "audit" = { "created_at" = "2024-08-24 00:10:56.415670004 +0000 UTC" - "created_by" = "s10qrydhDaic9GsWZ6BYpJfSK7wARDCv" + "created_by" = "sample_apikey" "modified_at" = "2024-08-24 00:11:37.523742051 +0000 UTC" - "modified_by" = "s10qrydhDaic9GsWZ6BYpJfSK7wARDCv" + "modified_by" = "sample_apikey" "version" = 2 } "cluster_id" = "ffffffff-aaaa-1414-eeee-00000000000" @@ -2029,7 +2029,7 @@ $ terraform destroy │ Warning: Provider development overrides are in effect │ │ The following provider development overrides are set in the CLI configuration: -│ - couchbasecloud/couchbase-capella in /Users/paulomee.de/go/bin +│ - couchbasecloud/couchbase-capella in /Users/$USER/go/bin │ │ The behavior may therefore not match any released version of the provider and applying changes may cause the state to become incompatible with published releases. ╵ @@ -2046,9 +2046,9 @@ Terraform will perform the following actions: - resource "couchbase-capella_network_peer" "new_network_peer" { - audit = { - created_at = "2024-08-24 00:10:56.415670004 +0000 UTC" -> null - - created_by = "s10qrydhDaic9GsWZ6BYpJfSK7wARDCv" -> null + - created_by = "sample_apikey" -> null - modified_at = "2024-08-24 00:11:37.523742051 +0000 UTC" -> null - - modified_by = "s10qrydhDaic9GsWZ6BYpJfSK7wARDCv" -> null + - modified_by = "sample_apikey" -> null - version = 2 -> null } -> null - cluster_id = "ffffffff-aaaa-1414-eeee-00000000000" -> null @@ -2083,9 +2083,9 @@ Changes to Outputs: - { - audit = { - created_at = "2024-08-24 00:10:56.415670004 +0000 UTC" - - created_by = "s10qrydhDaic9GsWZ6BYpJfSK7wARDCv" + - created_by = "sample_apikey" - modified_at = "2024-08-24 00:11:37.523742051 +0000 UTC" - - modified_by = "s10qrydhDaic9GsWZ6BYpJfSK7wARDCv" + - modified_by = "sample_apikey" - version = 2 } - id = "ffffffff-aaaa-1414-eeee-00000000000" @@ -2110,7 +2110,7 @@ Changes to Outputs: - { - audit = { - created_at = "2024-08-23 23:30:39.790107885 +0000 UTC" - - created_by = "s10qrydhDaic9GsWZ6BYpJfSK7wARDCv" + - created_by = "sample_apikey" - modified_at = "2024-08-23 23:35:39.359925093 +0000 UTC" - modified_by = "418653cc-a3c5-4943-9ff0-ee4d36a49ca3" - version = 6 @@ -2141,9 +2141,9 @@ Changes to Outputs: - new_network_peer = { - audit = { - created_at = "2024-08-24 00:10:56.415670004 +0000 UTC" - - created_by = "s10qrydhDaic9GsWZ6BYpJfSK7wARDCv" + - created_by = "sample_apikey" - modified_at = "2024-08-24 00:11:37.523742051 +0000 UTC" - - modified_by = "s10qrydhDaic9GsWZ6BYpJfSK7wARDCv" + - modified_by = "sample_apikey" - version = 2 } - cluster_id = "ffffffff-aaaa-1414-eeee-00000000000" diff --git a/examples/network_peer_command_azure/README.md b/examples/network_peer_command_azure/README.md index 47ca53fa..508b3c13 100644 --- a/examples/network_peer_command_azure/README.md +++ b/examples/network_peer_command_azure/README.md @@ -21,7 +21,7 @@ Sample Output: │ Warning: Provider development overrides are in effect │ │ The following provider development overrides are set in the CLI configuration: -│ - couchbasecloud/couchbase-capella in /Users/paulomee.de/go/bin +│ - couchbasecloud/couchbase-capella in /Users/$USER/go/bin │ │ The behavior may therefore not match any released version of the provider and applying changes may cause the state to become incompatible with published releases. ╵ From 8ce2a3d0ce93b4fcb83b673bb8f688e6ab0f3fc6 Mon Sep 17 00:00:00 2001 From: PaulomeeCb Date: Tue, 17 Sep 2024 13:59:32 -0700 Subject: [PATCH 21/23] Refactoring code as per review --- internal/errors/errors.go | 3 +++ internal/resources/network_peer.go | 40 +++++++++++++++++++++--------- internal/schema/network_peer.go | 35 +++++++++++++++----------- 3 files changed, 52 insertions(+), 26 deletions(-) diff --git a/internal/errors/errors.go b/internal/errors/errors.go index afecbaad..b546ae4c 100644 --- a/internal/errors/errors.go +++ b/internal/errors/errors.go @@ -166,6 +166,9 @@ var ( // ErrReadingAzureConfig is returned when a GCP disk read fails. ErrReadingAzureConfig = errors.New("failed to read Azure config, please contact Couchbase Capella Support") + // ErrReadingProviderConfig is returned when one or more of the fields in the provider config of the csp is missing. + ErrReadingProviderConfig = errors.New("failed to read the provider config as one or more of the fields in the config is missing, please contact Couchbase Capella Support") + // ErrBucketIdMissing is returned when an expected Bucket Id was not found after an import. ErrBucketIdMissing = errors.New("bucket ID is missing or was passed incorrectly, please check provider documentation for syntax") diff --git a/internal/resources/network_peer.go b/internal/resources/network_peer.go index 89f47fe6..f03fd960 100644 --- a/internal/resources/network_peer.go +++ b/internal/resources/network_peer.go @@ -459,28 +459,44 @@ func (n *NetworkPeer) getNetworkPeer(ctx context.Context, organizationId, projec return nil, fmt.Errorf("%s: %w", errors.ErrUnmarshallingResponse, err) } + if err := defineProviderForResponse(networkResp); err != nil { + return nil, err + } + + return &networkResp, nil +} + +// defineProviderForResponse sets the provider type in the retrieved network peer as per the fields populated in the provider config. +// If the provider type is not set through terraform separately in this manner, it will throw error as v4 get doesn't return it, but it's a field in resources. +func defineProviderForResponse(networkResp network_peer_api.GetNetworkPeeringRecordResponse) error { azure, err := networkResp.AsAZURE() - if err == nil && azure.AzureConfigData.AzureTenantId != "" { - networkResp.ProviderType = "azure" - } else if err != nil { - return nil, fmt.Errorf("%s: %w", errors.ErrReadingAzureConfig, err) + if err != nil { + return fmt.Errorf("%s: %w", errors.ErrReadingAzureConfig, err) } gcp, err := networkResp.AsGCP() - if err == nil && gcp.GCPConfigData.ProjectId != "" { - networkResp.ProviderType = "gcp" - } else if err != nil { - return nil, fmt.Errorf("%s: %w", errors.ErrReadingGCPConfig, err) + if err != nil { + return fmt.Errorf("%s: %w", errors.ErrReadingGCPConfig, err) } aws, err := networkResp.AsAWS() - if err == nil && aws.AWSConfigData.VpcId != "" { + if err != nil { + return fmt.Errorf("%s: %w", errors.ErrReadingAWSConfig, err) + } + + // if there is no error, set the provider type for the provider config as per the populated fields in the get response. + switch { + case azure.AzureConfigData.AzureTenantId != "": + networkResp.ProviderType = "azure" + case gcp.GCPConfigData.ProjectId != "": + networkResp.ProviderType = "gcp" + case aws.AWSConfigData.VpcId != "": networkResp.ProviderType = "aws" - } else if err != nil { - return nil, fmt.Errorf("%s: %w", errors.ErrReadingAWSConfig, err) + default: + return fmt.Errorf("%s: %w", errors.ErrReadingProviderConfig, err) } - return &networkResp, nil + return nil } func validateProviderTypeIsSameInPlanAndState(planProviderType, stateProviderType string) bool { diff --git a/internal/schema/network_peer.go b/internal/schema/network_peer.go index 68ec81a7..c6404df6 100644 --- a/internal/schema/network_peer.go +++ b/internal/schema/network_peer.go @@ -233,8 +233,24 @@ func NewNetworkPeer(ctx context.Context, networkPeer *network_peer_api.GetNetwor // morphToProviderConfig is used to convert ProviderConfig from json.RawMessage format to ProviderConfig type. func morphToProviderConfig(networkPeer *network_peer_api.GetNetworkPeeringRecordResponse) (ProviderConfig, error) { var newProviderConfig ProviderConfig + aws, err := networkPeer.AsAWS() - if err == nil && aws.AWSConfigData.VpcId != "" { + if err != nil { + return ProviderConfig{}, fmt.Errorf("%s: %w", errors.ErrReadingAWSConfig, err) + } + + gcp, err := networkPeer.AsGCP() + if err != nil { + return ProviderConfig{}, fmt.Errorf("%s: %w", errors.ErrReadingGCPConfig, err) + } + + azure, err := networkPeer.AsAZURE() + if err != nil { + return ProviderConfig{}, fmt.Errorf("%s: %w", errors.ErrReadingAzureConfig, err) + } + + switch { + case aws.AWSConfigData.VpcId != "": newProviderConfig.AWSConfig = &AWSConfig{ ProviderId: types.StringValue(aws.ProviderId), AccountId: types.StringValue(aws.AWSConfigData.AccountId), @@ -243,12 +259,7 @@ func morphToProviderConfig(networkPeer *network_peer_api.GetNetworkPeeringRecord Region: types.StringValue(aws.AWSConfigData.Region), } return newProviderConfig, nil - } else if err != nil { - return ProviderConfig{}, fmt.Errorf("%s: %w", errors.ErrReadingAWSConfig, err) - } - - gcp, err := networkPeer.AsGCP() - if err == nil && gcp.GCPConfigData.ProjectId != "" { + case gcp.GCPConfigData.ProjectId != "": newProviderConfig.GCPConfig = &GCPConfig{ ProviderId: types.StringValue(gcp.ProviderId), Cidr: types.StringValue(gcp.GCPConfigData.Cidr), @@ -257,11 +268,7 @@ func morphToProviderConfig(networkPeer *network_peer_api.GetNetworkPeeringRecord ServiceAccount: types.StringValue(gcp.GCPConfigData.ServiceAccount), } return newProviderConfig, nil - } else if err != nil { - return ProviderConfig{}, fmt.Errorf("%s: %w", errors.ErrReadingGCPConfig, err) - } - azure, err := networkPeer.AsAZURE() - if err == nil && azure.AzureConfigData.AzureTenantId != "" { + case azure.AzureConfigData.AzureTenantId != "": newProviderConfig.AzureConfig = &AzureConfig{ ProviderId: types.StringValue(azure.ProviderId), Cidr: types.StringValue(azure.AzureConfigData.Cidr), @@ -271,8 +278,8 @@ func morphToProviderConfig(networkPeer *network_peer_api.GetNetworkPeeringRecord AzureTenantId: types.StringValue(azure.AzureConfigData.AzureTenantId), } return newProviderConfig, nil - } else if err != nil { - return ProviderConfig{}, fmt.Errorf("%s: %w", errors.ErrReadingAzureConfig, err) + default: + return ProviderConfig{}, fmt.Errorf("%s: %w", errors.ErrReadingProviderConfig, err) } return newProviderConfig, nil } From 2cad0ec4b77e980aef2f756bbecb2d6f1c5927a1 Mon Sep 17 00:00:00 2001 From: PaulomeeCb Date: Tue, 17 Sep 2024 14:09:04 -0700 Subject: [PATCH 22/23] reverting schema code --- internal/schema/network_peer.go | 35 +++++++++++++-------------------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/internal/schema/network_peer.go b/internal/schema/network_peer.go index c6404df6..68ec81a7 100644 --- a/internal/schema/network_peer.go +++ b/internal/schema/network_peer.go @@ -233,24 +233,8 @@ func NewNetworkPeer(ctx context.Context, networkPeer *network_peer_api.GetNetwor // morphToProviderConfig is used to convert ProviderConfig from json.RawMessage format to ProviderConfig type. func morphToProviderConfig(networkPeer *network_peer_api.GetNetworkPeeringRecordResponse) (ProviderConfig, error) { var newProviderConfig ProviderConfig - aws, err := networkPeer.AsAWS() - if err != nil { - return ProviderConfig{}, fmt.Errorf("%s: %w", errors.ErrReadingAWSConfig, err) - } - - gcp, err := networkPeer.AsGCP() - if err != nil { - return ProviderConfig{}, fmt.Errorf("%s: %w", errors.ErrReadingGCPConfig, err) - } - - azure, err := networkPeer.AsAZURE() - if err != nil { - return ProviderConfig{}, fmt.Errorf("%s: %w", errors.ErrReadingAzureConfig, err) - } - - switch { - case aws.AWSConfigData.VpcId != "": + if err == nil && aws.AWSConfigData.VpcId != "" { newProviderConfig.AWSConfig = &AWSConfig{ ProviderId: types.StringValue(aws.ProviderId), AccountId: types.StringValue(aws.AWSConfigData.AccountId), @@ -259,7 +243,12 @@ func morphToProviderConfig(networkPeer *network_peer_api.GetNetworkPeeringRecord Region: types.StringValue(aws.AWSConfigData.Region), } return newProviderConfig, nil - case gcp.GCPConfigData.ProjectId != "": + } else if err != nil { + return ProviderConfig{}, fmt.Errorf("%s: %w", errors.ErrReadingAWSConfig, err) + } + + gcp, err := networkPeer.AsGCP() + if err == nil && gcp.GCPConfigData.ProjectId != "" { newProviderConfig.GCPConfig = &GCPConfig{ ProviderId: types.StringValue(gcp.ProviderId), Cidr: types.StringValue(gcp.GCPConfigData.Cidr), @@ -268,7 +257,11 @@ func morphToProviderConfig(networkPeer *network_peer_api.GetNetworkPeeringRecord ServiceAccount: types.StringValue(gcp.GCPConfigData.ServiceAccount), } return newProviderConfig, nil - case azure.AzureConfigData.AzureTenantId != "": + } else if err != nil { + return ProviderConfig{}, fmt.Errorf("%s: %w", errors.ErrReadingGCPConfig, err) + } + azure, err := networkPeer.AsAZURE() + if err == nil && azure.AzureConfigData.AzureTenantId != "" { newProviderConfig.AzureConfig = &AzureConfig{ ProviderId: types.StringValue(azure.ProviderId), Cidr: types.StringValue(azure.AzureConfigData.Cidr), @@ -278,8 +271,8 @@ func morphToProviderConfig(networkPeer *network_peer_api.GetNetworkPeeringRecord AzureTenantId: types.StringValue(azure.AzureConfigData.AzureTenantId), } return newProviderConfig, nil - default: - return ProviderConfig{}, fmt.Errorf("%s: %w", errors.ErrReadingProviderConfig, err) + } else if err != nil { + return ProviderConfig{}, fmt.Errorf("%s: %w", errors.ErrReadingAzureConfig, err) } return newProviderConfig, nil } From ef8f167574dc06745516434005ea13d1f5e1444d Mon Sep 17 00:00:00 2001 From: PaulomeeCb Date: Tue, 17 Sep 2024 14:20:26 -0700 Subject: [PATCH 23/23] Refactoring schema code again to resolve UT errors --- internal/schema/network_peer.go | 37 ++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/internal/schema/network_peer.go b/internal/schema/network_peer.go index 68ec81a7..6d675f6d 100644 --- a/internal/schema/network_peer.go +++ b/internal/schema/network_peer.go @@ -233,8 +233,24 @@ func NewNetworkPeer(ctx context.Context, networkPeer *network_peer_api.GetNetwor // morphToProviderConfig is used to convert ProviderConfig from json.RawMessage format to ProviderConfig type. func morphToProviderConfig(networkPeer *network_peer_api.GetNetworkPeeringRecordResponse) (ProviderConfig, error) { var newProviderConfig ProviderConfig + aws, err := networkPeer.AsAWS() - if err == nil && aws.AWSConfigData.VpcId != "" { + if err != nil { + return ProviderConfig{}, fmt.Errorf("%s: %w", errors.ErrReadingAWSConfig, err) + } + + gcp, err := networkPeer.AsGCP() + if err != nil { + return ProviderConfig{}, fmt.Errorf("%s: %w", errors.ErrReadingGCPConfig, err) + } + + azure, err := networkPeer.AsAZURE() + if err != nil { + return ProviderConfig{}, fmt.Errorf("%s: %w", errors.ErrReadingAzureConfig, err) + } + + switch { + case aws.AWSConfigData.VpcId != "": newProviderConfig.AWSConfig = &AWSConfig{ ProviderId: types.StringValue(aws.ProviderId), AccountId: types.StringValue(aws.AWSConfigData.AccountId), @@ -243,12 +259,7 @@ func morphToProviderConfig(networkPeer *network_peer_api.GetNetworkPeeringRecord Region: types.StringValue(aws.AWSConfigData.Region), } return newProviderConfig, nil - } else if err != nil { - return ProviderConfig{}, fmt.Errorf("%s: %w", errors.ErrReadingAWSConfig, err) - } - - gcp, err := networkPeer.AsGCP() - if err == nil && gcp.GCPConfigData.ProjectId != "" { + case gcp.GCPConfigData.ProjectId != "": newProviderConfig.GCPConfig = &GCPConfig{ ProviderId: types.StringValue(gcp.ProviderId), Cidr: types.StringValue(gcp.GCPConfigData.Cidr), @@ -257,11 +268,7 @@ func morphToProviderConfig(networkPeer *network_peer_api.GetNetworkPeeringRecord ServiceAccount: types.StringValue(gcp.GCPConfigData.ServiceAccount), } return newProviderConfig, nil - } else if err != nil { - return ProviderConfig{}, fmt.Errorf("%s: %w", errors.ErrReadingGCPConfig, err) - } - azure, err := networkPeer.AsAZURE() - if err == nil && azure.AzureConfigData.AzureTenantId != "" { + case azure.AzureConfigData.AzureTenantId != "": newProviderConfig.AzureConfig = &AzureConfig{ ProviderId: types.StringValue(azure.ProviderId), Cidr: types.StringValue(azure.AzureConfigData.Cidr), @@ -271,10 +278,10 @@ func morphToProviderConfig(networkPeer *network_peer_api.GetNetworkPeeringRecord AzureTenantId: types.StringValue(azure.AzureConfigData.AzureTenantId), } return newProviderConfig, nil - } else if err != nil { - return ProviderConfig{}, fmt.Errorf("%s: %w", errors.ErrReadingAzureConfig, err) + default: + return ProviderConfig{}, fmt.Errorf("%s: %w", errors.ErrReadingProviderConfig, err) } - return newProviderConfig, nil + } // AttributeTypes returns a mapping of field names to their respective attribute types for the PeeringStatus struct.