From c393b56e8c13121979d89e7db7b75714fe4f2c56 Mon Sep 17 00:00:00 2001 From: Ian Reyes Date: Mon, 4 Dec 2023 03:27:16 -0500 Subject: [PATCH] Add new service Logs Router to IBM Terraform Provider (#4945) * Added new service Logs Router to IBM Terraform Provider * Ran detect-secrets and re-generated secrets.baseline * Added emptycredentialsError check for Logs Router Client Error Signed-off-by: Ian Reyes * Removed redundant general provider set up information. Fixed Service Subcategories Signed-off-by: Ian Reyes --------- Signed-off-by: Ian Reyes --- .secrets.baseline | 22 +- examples/ibm-logs-router/README.md | 81 ++++++ examples/ibm-logs-router/main.tf | 17 ++ examples/ibm-logs-router/outputs.tf | 6 + examples/ibm-logs-router/variables.tf | 33 +++ examples/ibm-logs-router/versions.tf | 9 + go.mod | 1 + go.sum | 2 + ibm/conns/config.go | 28 ++ ibm/provider/provider.go | 8 + ibm/service/logsrouter/README.md | 11 + .../data_source_ibm_logs_router_tenant.go | 118 ++++++++ ...data_source_ibm_logs_router_tenant_test.go | 44 +++ .../resource_ibm_logs_router_tenant.go | 266 ++++++++++++++++++ .../resource_ibm_logs_router_tenant_test.go | 128 +++++++++ website/allowed-subcategories.txt | 1 + .../docs/d/logs_router_tenant.html.markdown | 52 ++++ .../docs/r/logs_router_tenant.html.markdown | 60 ++++ 18 files changed, 881 insertions(+), 6 deletions(-) create mode 100644 examples/ibm-logs-router/README.md create mode 100644 examples/ibm-logs-router/main.tf create mode 100644 examples/ibm-logs-router/outputs.tf create mode 100644 examples/ibm-logs-router/variables.tf create mode 100644 examples/ibm-logs-router/versions.tf create mode 100644 ibm/service/logsrouter/README.md create mode 100644 ibm/service/logsrouter/data_source_ibm_logs_router_tenant.go create mode 100644 ibm/service/logsrouter/data_source_ibm_logs_router_tenant_test.go create mode 100644 ibm/service/logsrouter/resource_ibm_logs_router_tenant.go create mode 100644 ibm/service/logsrouter/resource_ibm_logs_router_tenant_test.go create mode 100644 website/docs/d/logs_router_tenant.html.markdown create mode 100644 website/docs/r/logs_router_tenant.html.markdown diff --git a/.secrets.baseline b/.secrets.baseline index f7d1438953..3a62206e9a 100644 --- a/.secrets.baseline +++ b/.secrets.baseline @@ -786,7 +786,7 @@ "hashed_secret": "9184b0c38101bf24d78b2bb0d044deb1d33696fc", "is_secret": false, "is_verified": false, - "line_number": 131, + "line_number": 132, "type": "Secret Keyword", "verified_result": null }, @@ -794,7 +794,7 @@ "hashed_secret": "c427f185ddcb2440be9b77c8e45f1cd487a2e790", "is_secret": false, "is_verified": false, - "line_number": 1438, + "line_number": 1449, "type": "Base64 High Entropy String", "verified_result": null }, @@ -802,7 +802,7 @@ "hashed_secret": "1f7e33de15e22de9d2eaf502df284ed25ca40018", "is_secret": false, "is_verified": false, - "line_number": 1505, + "line_number": 1516, "type": "Secret Keyword", "verified_result": null }, @@ -810,7 +810,7 @@ "hashed_secret": "1f614c2eb6b3da22d89bd1b9fd47d7cb7c8fc670", "is_secret": false, "is_verified": false, - "line_number": 3298, + "line_number": 3325, "type": "Secret Keyword", "verified_result": null }, @@ -818,7 +818,7 @@ "hashed_secret": "7abfce65b8504403afc25c9790f358d513dfbcc6", "is_secret": false, "is_verified": false, - "line_number": 3311, + "line_number": 3338, "type": "Secret Keyword", "verified_result": null }, @@ -826,7 +826,7 @@ "hashed_secret": "0c2d85bf9a9b1579b16f220a4ea8c3d62b2e24b1", "is_secret": false, "is_verified": false, - "line_number": 3352, + "line_number": 3379, "type": "Secret Keyword", "verified_result": null } @@ -4505,6 +4505,16 @@ "verified_result": null } ], + "website/docs/r/logs_router_tenant.html.markdown": [ + { + "hashed_secret": "d47dcacc720a39e236679ac3e311a0d58bb6519e", + "is_secret": false, + "is_verified": false, + "line_number": 78, + "type": "Secret Keyword", + "verified_result": null + } + ], "website/docs/r/metrics_router_route.html.markdown": [ { "hashed_secret": "d47dcacc720a39e236679ac3e311a0d58bb6519e", diff --git a/examples/ibm-logs-router/README.md b/examples/ibm-logs-router/README.md new file mode 100644 index 0000000000..51da09060a --- /dev/null +++ b/examples/ibm-logs-router/README.md @@ -0,0 +1,81 @@ +# Example for IBM Logs Router V1 + +This example illustrates how to use IBM LogsRouterV1 + +The following types of resources are supported: + +* logs_router_tenant + +## Usage + +To run this example, execute the following commands: + +```bash +$ terraform init +$ terraform plan +$ terraform apply +``` + +Run `terraform destroy` when you don't need these resources. + + +## IbmLogsRouterV1 resources + +logs_router_tenant resource: + +```hcl +resource "logs_router_tenant" "logs_router_tenant_instance" { + target_type = var.logs_router_tenant_target_type + target_host = var.logs_router_tenant_target_host + target_port = var.logs_router_tenant_target_port + target_instance_crn = var.logs_router_tenant_target_instance_crn +} +``` + +## IbmLogsRouterV1 data sources + +logs_router_tenant data source: + +```hcl +data "logs_router_tenant" "logs_router_tenant_instance" { + tenant_id = ibm_logs_router_tenant.logs_router_tenant_instance.id +} +``` + +## Assumptions + +1. TODO + +## Notes + +1. TODO + +## Requirements + +| Name | Version | +|------|---------| +| terraform | ~> 0.12 | + +## Providers + +| Name | Version | +|------|---------| +| ibm | 1.13.1 | + +## Inputs + +| Name | Description | Type | Required | +|------|-------------|------|---------| +| ibmcloud\_api\_key | IBM Cloud API key | `string` | true | +| target_type | Type of log-sink. | `string` | true | +| target_host | Host name of log-sink. | `string` | true | +| target_port | Network port of log sink. | `number` | true | +| target_instance_crn | Cloud resource name of the log-sink target instance. | `string` | true | +| tenant_id | The instance ID of the tenant. | `` | true | + +## Outputs + +| Name | Description | +|------|-------------| +| logs_router_tenant | logs_router_tenant object | +| logs_router_tenant | logs_router_tenant object | diff --git a/examples/ibm-logs-router/main.tf b/examples/ibm-logs-router/main.tf new file mode 100644 index 0000000000..1be39ee095 --- /dev/null +++ b/examples/ibm-logs-router/main.tf @@ -0,0 +1,17 @@ +provider "ibm" { + ibmcloud_api_key = var.ibmcloud_api_key +} + +// Provision logs_router_tenant resource instance +resource "ibm_logs_router_tenant" "logs_router_tenant_instance" { + target_type = var.logs_router_tenant_target_type + target_host = var.logs_router_tenant_target_host + target_port = var.logs_router_tenant_target_port + target_instance_crn = var.logs_router_tenant_target_instance_crn +} + +// Create logs_router_tenant data source +data "ibm_logs_router_tenant" "logs_router_tenant_instance" { + tenant_id = ibm_logs_router_tenant.logs_router_tenant_instance.id +} + diff --git a/examples/ibm-logs-router/outputs.tf b/examples/ibm-logs-router/outputs.tf new file mode 100644 index 0000000000..813aeb5bcb --- /dev/null +++ b/examples/ibm-logs-router/outputs.tf @@ -0,0 +1,6 @@ +// This output allows logs_router_tenant data to be referenced by other resources and the terraform CLI +// Modify this output if only certain data should be exposed +output "ibm_logs_router_tenant" { + value = ibm_logs_router_tenant.logs_router_tenant_instance + description = "logs_router_tenant resource instance" +} diff --git a/examples/ibm-logs-router/variables.tf b/examples/ibm-logs-router/variables.tf new file mode 100644 index 0000000000..34a9f372ff --- /dev/null +++ b/examples/ibm-logs-router/variables.tf @@ -0,0 +1,33 @@ +variable "ibmcloud_api_key" { + description = "IBM Cloud API key" + type = string +} + +// Resource arguments for logs_router_tenant +variable "logs_router_tenant_target_type" { + description = "Type of log-sink." + type = string + default = "logdna" +} +variable "logs_router_tenant_target_host" { + description = "Host name of log-sink." + type = string + default = "www.example.com" +} +variable "logs_router_tenant_target_port" { + description = "Network port of log sink." + type = number + default = 10 +} +variable "logs_router_tenant_target_instance_crn" { + description = "Cloud resource name of the log-sink target instance." + type = string + default = "crn:v1:bluemix:public:logdna:us-east:a/36ff82794a734d7580b90c97b0327d28:f08aea7c-dde9-4452-b552-225af4b51eaa::" +} + +// Data source arguments for logs_router_tenant +variable "logs_router_tenant_tenant_id" { + description = "The instance ID of the tenant." + type = string + default = "f3a466c9-c4db-4eee-95cc-ba82db58e2b5" +} diff --git a/examples/ibm-logs-router/versions.tf b/examples/ibm-logs-router/versions.tf new file mode 100644 index 0000000000..54c9d03e8d --- /dev/null +++ b/examples/ibm-logs-router/versions.tf @@ -0,0 +1,9 @@ +terraform { + required_version = ">= 1.0" + required_providers { + ibm = { + source = "IBM-Cloud/ibm" + version = "1.52.0-beta0" + } + } +} diff --git a/go.mod b/go.mod index 3bb6d00084..bffd2441f8 100644 --- a/go.mod +++ b/go.mod @@ -23,6 +23,7 @@ require ( github.com/IBM/ibm-hpcs-tke-sdk v0.0.0-20211109141421-a4b61b05f7d1 github.com/IBM/ibm-hpcs-uko-sdk v0.0.20-beta github.com/IBM/keyprotect-go-client v0.12.2 + github.com/IBM/logs-router-go-sdk v1.0.0 github.com/IBM/networking-go-sdk v0.42.2 github.com/IBM/platform-services-go-sdk v0.54.0 github.com/IBM/project-go-sdk v0.1.1 diff --git a/go.sum b/go.sum index 2deeef865a..4477787f09 100644 --- a/go.sum +++ b/go.sum @@ -153,6 +153,8 @@ github.com/IBM/ibm-hpcs-uko-sdk v0.0.20-beta/go.mod h1:MLVNHMYoKsvovJZ4v1gQCpIYt github.com/IBM/keyprotect-go-client v0.5.1/go.mod h1:5TwDM/4FRJq1ZOlwQL1xFahLWQ3TveR88VmL1u3njyI= github.com/IBM/keyprotect-go-client v0.12.2 h1:Cjxcqin9Pl0xz3MnxdiVd4v/eIa79xL3hQpSbwOr/DQ= github.com/IBM/keyprotect-go-client v0.12.2/go.mod h1:yr8h2noNgU8vcbs+vhqoXp3Lmv73PI0zAc6VMgFvWwM= +github.com/IBM/logs-router-go-sdk v1.0.0 h1:cGBjf7wJye/WuzFljqN7yB8ToIxLIiffWaQGW9rSTcI= +github.com/IBM/logs-router-go-sdk v1.0.0/go.mod h1:FJpyZctp5DmRms/MtvRUuWBF/CAk76WJzAsJc4EIM/Y= github.com/IBM/networking-go-sdk v0.42.2 h1:caqjx4jyFHi10Vlf3skHvlL6K3YJRVstsmCBmvdyqkA= github.com/IBM/networking-go-sdk v0.42.2/go.mod h1:lTUZwtUkMANMnrLHFIgRhHrkBfwASY/Iho1fabaPHxo= github.com/IBM/platform-services-go-sdk v0.54.0 h1:WjHWm9ZAJvlq07E1WXXtEe+d/B0sazWD6cEWVT7EMLU= diff --git a/ibm/conns/config.go b/ibm/conns/config.go index ff89bd307f..88eb394709 100644 --- a/ibm/conns/config.go +++ b/ibm/conns/config.go @@ -29,6 +29,7 @@ import ( "github.com/IBM/go-sdk-core/v5/core" cosconfig "github.com/IBM/ibm-cos-sdk-go-config/resourceconfigurationv1" kp "github.com/IBM/keyprotect-go-client" + "github.com/IBM/logs-router-go-sdk/ibmlogsrouteropenapi30v0" cisalertsv1 "github.com/IBM/networking-go-sdk/alertsv1" cisoriginpull "github.com/IBM/networking-go-sdk/authenticatedoriginpullapiv1" cisbotanalyticsv1 "github.com/IBM/networking-go-sdk/botanalyticsv1" @@ -228,6 +229,7 @@ type ClientSession interface { ResourceManagementAPIv2() (managementv2.ResourceManagementAPIv2, error) ResourceControllerAPI() (controller.ResourceControllerAPI, error) ResourceControllerAPIV2() (controllerv2.ResourceControllerAPIV2, error) + IbmLogsRouterOpenApi30V0() (*ibmlogsrouteropenapi30v0.IbmLogsRouterOpenApi30V0, error) SoftLayerSession() *slsession.Session IBMPISession() (*ibmpisession.IBMPISession, error) UserManagementAPI() (usermanagementv2.UserManagementAPI, error) @@ -542,6 +544,10 @@ type clientSession struct { secretsManagerClient *secretsmanagerv2.SecretsManagerV2 secretsManagerClientErr error + // Logs Routing + ibmLogsRouterOpenApi30Client *ibmlogsrouteropenapi30v0.IbmLogsRouterOpenApi30V0 + ibmLogsRouterOpenApi30ClientErr error + // Schematics service options schematicsClient *schematicsv1.SchematicsV1 schematicsClientErr error @@ -1169,6 +1175,11 @@ func (session clientSession) MetricsRouterV3() (*metricsrouterv3.MetricsRouterV3 return session.metricsRouterClient, session.metricsRouterClientErr } +// Logs Router API +func (session clientSession) IbmLogsRouterOpenApi30V0() (*ibmlogsrouteropenapi30v0.IbmLogsRouterOpenApi30V0, error) { + return session.ibmLogsRouterOpenApi30Client, session.ibmLogsRouterOpenApi30ClientErr +} + func (session clientSession) ESschemaRegistrySession() (*schemaregistryv1.SchemaregistryV1, error) { return session.esSchemaRegistryClient, session.esSchemaRegistryErr } @@ -1296,6 +1307,7 @@ func (c *Config) ClientSession() (interface{}, error) { session.cdToolchainClientErr = errEmptyBluemixCredentials session.codeEngineClientErr = errEmptyBluemixCredentials session.projectClientErr = errEmptyBluemixCredentials + session.ibmLogsRouterOpenApi30ClientErr = errEmptyBluemixCredentials return session, nil } @@ -1678,6 +1690,22 @@ func (c *Config) ClientSession() (interface{}, error) { }) } + // LOGS ROUTER service + ibmLogsRouterOpenApi30ClientOptions := &ibmlogsrouteropenapi30v0.IbmLogsRouterOpenApi30V0Options{ + Authenticator: authenticator, + } + session.ibmLogsRouterOpenApi30Client, err = ibmlogsrouteropenapi30v0.NewIbmLogsRouterOpenApi30V0(ibmLogsRouterOpenApi30ClientOptions) + if err == nil { + // Enable retries for API calls + session.ibmLogsRouterOpenApi30Client.Service.EnableRetries(c.RetryCount, c.RetryDelay) + // Add custom header for analytics + session.ibmLogsRouterOpenApi30Client.SetDefaultHeaders(gohttp.Header{ + "X-Original-User-Agent": {fmt.Sprintf("terraform-provider-ibm/%s", version.Version)}, + }) + } else { + session.ibmLogsRouterOpenApi30ClientErr = fmt.Errorf("Error occurred while configuring IBM logs-router service: %q", err) + } + // ATRACKER Version 2 var atrackerClientV2URL string var atrackerURLV2Err error diff --git a/ibm/provider/provider.go b/ibm/provider/provider.go index 9a0e61277b..aa758ebf66 100644 --- a/ibm/provider/provider.go +++ b/ibm/provider/provider.go @@ -38,6 +38,7 @@ import ( "github.com/IBM-Cloud/terraform-provider-ibm/ibm/service/iampolicy" "github.com/IBM-Cloud/terraform-provider-ibm/ibm/service/kms" "github.com/IBM-Cloud/terraform-provider-ibm/ibm/service/kubernetes" + "github.com/IBM-Cloud/terraform-provider-ibm/ibm/service/logsrouter" "github.com/IBM-Cloud/terraform-provider-ibm/ibm/service/metricsrouter" "github.com/IBM-Cloud/terraform-provider-ibm/ibm/service/power" "github.com/IBM-Cloud/terraform-provider-ibm/ibm/service/project" @@ -743,6 +744,9 @@ func Provider() *schema.Provider { "ibm_metrics_router_targets": metricsrouter.DataSourceIBMMetricsRouterTargets(), "ibm_metrics_router_routes": metricsrouter.DataSourceIBMMetricsRouterRoutes(), + // Logs Router + "ibm_logs_router_tenant": logsrouter.DataSourceIbmLogsRouterTenant(), + // Security and Complaince Center(soon to be deprecated) "ibm_scc_account_location": scc.DataSourceIBMSccAccountLocation(), "ibm_scc_account_locations": scc.DataSourceIBMSccAccountLocations(), @@ -1276,6 +1280,9 @@ func Provider() *schema.Provider { "ibm_metrics_router_route": metricsrouter.ResourceIBMMetricsRouterRoute(), "ibm_metrics_router_settings": metricsrouter.ResourceIBMMetricsRouterSettings(), + // Logs Router + "ibm_logs_router_tenant": logsrouter.ResourceIbmLogsRouterTenant(), + // Security and Compliance Center(soon to be deprecated) "ibm_scc_account_settings": scc.ResourceIBMSccAccountSettings(), "ibm_scc_rule_attachment": scc.ResourceIBMSccRuleAttachment(), @@ -1540,6 +1547,7 @@ func Validator() validate.ValidatorDict { "ibm_metrics_router_target": metricsrouter.ResourceIBMMetricsRouterTargetValidator(), "ibm_metrics_router_route": metricsrouter.ResourceIBMMetricsRouterRouteValidator(), "ibm_metrics_router_settings": metricsrouter.ResourceIBMMetricsRouterSettingsValidator(), + "ibm_logs_router_tenant": logsrouter.ResourceIbmLogsRouterTenantValidator(), "ibm_satellite_endpoint": satellite.ResourceIBMSatelliteEndpointValidator(), "ibm_cbr_zone": contextbasedrestrictions.ResourceIBMCbrZoneValidator(), "ibm_cbr_rule": contextbasedrestrictions.ResourceIBMCbrRuleValidator(), diff --git a/ibm/service/logsrouter/README.md b/ibm/service/logsrouter/README.md new file mode 100644 index 0000000000..350106c42d --- /dev/null +++ b/ibm/service/logsrouter/README.md @@ -0,0 +1,11 @@ +# Terraform IBM Provider + +This area is primarily for IBM provider contributors and maintainers. For information on _using_ Terraform and the IBM provider, see the links below. + + +## Handy Links +* [Find out about contributing](../../../CONTRIBUTING.md) to the IBM provider! +* IBM Provider Docs: [Home](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs) +* IBM Provider Docs: [One of the resources](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/logs_router_tenant) +* IBM API Docs: [IBM API Docs for IBM Cloud Logs Router](https://test.cloud.ibm.com/apidocs/logs-router-service-api) +* IBM SDK: [IBM SDK for IBM Cloud Logs Router](https://github.com/IBM/logs-router-go-sdk) diff --git a/ibm/service/logsrouter/data_source_ibm_logs_router_tenant.go b/ibm/service/logsrouter/data_source_ibm_logs_router_tenant.go new file mode 100644 index 0000000000..db12580145 --- /dev/null +++ b/ibm/service/logsrouter/data_source_ibm_logs_router_tenant.go @@ -0,0 +1,118 @@ +// Copyright IBM Corp. 2023 All Rights Reserved. +// Licensed under the Mozilla Public License v2.0 + +package logsrouter + +import ( + "context" + "fmt" + "log" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/IBM-Cloud/terraform-provider-ibm/ibm/conns" + "github.com/IBM-Cloud/terraform-provider-ibm/ibm/flex" + "github.com/IBM/logs-router-go-sdk/ibmlogsrouteropenapi30v0" + + "github.com/IBM/go-sdk-core/v5/core" + "github.com/go-openapi/strfmt" +) + +func DataSourceIbmLogsRouterTenant() *schema.Resource { + return &schema.Resource{ + ReadContext: dataSourceIbmLogsRouterTenantRead, + + Schema: map[string]*schema.Schema{ + "tenant_id": &schema.Schema{ + Type: schema.TypeString, + Required: true, + Description: "The instance ID of the tenant.", + }, + "account_id": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + Description: "The account ID the tenant belongs to.", + }, + "target_type": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + Description: "Type of log-sink.", + }, + "target_host": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + Description: "Host name of log-sink.", + }, + "target_port": &schema.Schema{ + Type: schema.TypeInt, + Computed: true, + Description: "Network port of log sink.", + }, + "target_instance_crn": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + Description: "Cloud resource name of the log-sink target instance.", + }, + "created_at": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + Description: "Time stamp the tenant was originally created.", + }, + "updated_at": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + Description: "time stamp the tenant was last updated.", + }, + }, + } +} + +func dataSourceIbmLogsRouterTenantRead(context context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + ibmLogsRouterOpenApi30Client, err := meta.(conns.ClientSession).IbmLogsRouterOpenApi30V0() + if err != nil { + return diag.FromErr(err) + } + + getTenantDetailOptions := &ibmlogsrouteropenapi30v0.GetTenantDetailOptions{} + + getTenantDetailOptions.SetTenantID(core.UUIDPtr(strfmt.UUID(d.Get("tenant_id").(string)))) + + tenantDetailsResponse, response, err := ibmLogsRouterOpenApi30Client.GetTenantDetailWithContext(context, getTenantDetailOptions) + if err != nil { + log.Printf("[DEBUG] GetTenantDetailWithContext failed %s\n%s", err, response) + return diag.FromErr(fmt.Errorf("GetTenantDetailWithContext failed %s\n%s", err, response)) + } + + d.SetId(fmt.Sprintf("%s", *getTenantDetailOptions.TenantID)) + + if err = d.Set("account_id", tenantDetailsResponse.AccountID); err != nil { + return diag.FromErr(fmt.Errorf("Error setting account_id: %s", err)) + } + + if err = d.Set("target_type", tenantDetailsResponse.TargetType); err != nil { + return diag.FromErr(fmt.Errorf("Error setting target_type: %s", err)) + } + + if err = d.Set("target_host", tenantDetailsResponse.TargetHost); err != nil { + return diag.FromErr(fmt.Errorf("Error setting target_host: %s", err)) + } + + if err = d.Set("target_port", flex.IntValue(tenantDetailsResponse.TargetPort)); err != nil { + return diag.FromErr(fmt.Errorf("Error setting target_port: %s", err)) + } + + if err = d.Set("target_instance_crn", tenantDetailsResponse.TargetInstanceCrn); err != nil { + return diag.FromErr(fmt.Errorf("Error setting target_instance_crn: %s", err)) + } + + if err = d.Set("created_at", tenantDetailsResponse.CreatedAt); err != nil { + return diag.FromErr(fmt.Errorf("Error setting created_at: %s", err)) + } + + if err = d.Set("updated_at", tenantDetailsResponse.UpdatedAt); err != nil { + return diag.FromErr(fmt.Errorf("Error setting updated_at: %s", err)) + } + + return nil +} diff --git a/ibm/service/logsrouter/data_source_ibm_logs_router_tenant_test.go b/ibm/service/logsrouter/data_source_ibm_logs_router_tenant_test.go new file mode 100644 index 0000000000..597acdbded --- /dev/null +++ b/ibm/service/logsrouter/data_source_ibm_logs_router_tenant_test.go @@ -0,0 +1,44 @@ +// Copyright IBM Corp. 2023 All Rights Reserved. +// Licensed under the Mozilla Public License v2.0 + +package logsrouter_test + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + + acc "github.com/IBM-Cloud/terraform-provider-ibm/ibm/acctest" +) + +func TestAccIbmLogsRouterTenantDataSourceBasic(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { acc.TestAccPreCheck(t) }, + Providers: acc.TestAccProviders, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccCheckIbmLogsRouterTenantDataSourceConfigBasic(), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet("data.ibm_logs_router_tenant.logs_router_tenant_instance", "id"), + resource.TestCheckResourceAttrSet("data.ibm_logs_router_tenant.logs_router_tenant_instance", "tenant_id"), + ), + }, + }, + }) +} + +func testAccCheckIbmLogsRouterTenantDataSourceConfigBasic() string { + return fmt.Sprintf(` + resource "ibm_logs_router_tenant" "logs_router_tenant_instance" { + target_type = "logdna" + target_host = "tf-target-host-01" + target_port = 42 + target_instance_crn = "crn:v1:bluemix:public:logdna:eu-de:a/3516b8fa0a174a71899f5affa4f18d78:3517d2ed-9429-af34-ad52-34278391cbca::" + access_credential = "test-credential" + } + data "ibm_logs_router_tenant" "logs_router_tenant_instance" { + tenant_id = ibm_logs_router_tenant.logs_router_tenant_instance.id + } + `) +} diff --git a/ibm/service/logsrouter/resource_ibm_logs_router_tenant.go b/ibm/service/logsrouter/resource_ibm_logs_router_tenant.go new file mode 100644 index 0000000000..02da4c81c0 --- /dev/null +++ b/ibm/service/logsrouter/resource_ibm_logs_router_tenant.go @@ -0,0 +1,266 @@ +// Copyright IBM Corp. 2023 All Rights Reserved. +// Licensed under the Mozilla Public License v2.0 + +package logsrouter + +import ( + "context" + "fmt" + "log" + + "github.com/go-openapi/strfmt" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/IBM-Cloud/terraform-provider-ibm/ibm/conns" + "github.com/IBM-Cloud/terraform-provider-ibm/ibm/flex" + "github.com/IBM-Cloud/terraform-provider-ibm/ibm/validate" + "github.com/IBM/go-sdk-core/v5/core" + "github.com/IBM/logs-router-go-sdk/ibmlogsrouteropenapi30v0" +) + +func ResourceIbmLogsRouterTenant() *schema.Resource { + return &schema.Resource{ + CreateContext: resourceIbmLogsRouterTenantCreate, + ReadContext: resourceIbmLogsRouterTenantRead, + UpdateContext: resourceIbmLogsRouterTenantUpdate, + DeleteContext: resourceIbmLogsRouterTenantDelete, + Importer: &schema.ResourceImporter{}, + + Schema: map[string]*schema.Schema{ + "target_type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.InvokeValidator("ibm_logs_router_tenant", "target_type"), + Description: "Type of log-sink.", + }, + "target_host": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.InvokeValidator("ibm_logs_router_tenant", "target_host"), + Description: "Host name of log-sink.", + }, + "target_port": { + Type: schema.TypeInt, + Required: true, + Description: "Network port of log sink.", + }, + "target_instance_crn": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.InvokeValidator("ibm_logs_router_tenant", "target_instance_crn"), + Description: "Cloud resource name of the log-sink target instance.", + }, + "access_credential": { + Type: schema.TypeString, + Required: true, + Sensitive: true, + ValidateFunc: validate.InvokeValidator("ibm_logs_router_tenant", "access_credential"), + Description: "Secret to connect to the log-sink", + }, + "account_id": { + Type: schema.TypeString, + Computed: true, + Description: "The account ID the tenant belongs to.", + }, + "created_at": { + Type: schema.TypeString, + Computed: true, + Description: "Time stamp the tenant was originally created.", + }, + "updated_at": { + Type: schema.TypeString, + Computed: true, + Description: "time stamp the tenant was last updated.", + }, + }, + } +} + +func ResourceIbmLogsRouterTenantValidator() *validate.ResourceValidator { + validateSchema := make([]validate.ValidateSchema, 0) + validateSchema = append(validateSchema, + validate.ValidateSchema{ + Identifier: "target_type", + ValidateFunctionIdentifier: validate.ValidateRegexpLen, + Type: validate.TypeString, + Required: true, + Regexp: `[a-z,A-Z,0-9,-]`, + MinValueLength: 1, + MaxValueLength: 32, + }, + validate.ValidateSchema{ + Identifier: "target_host", + ValidateFunctionIdentifier: validate.ValidateRegexpLen, + Type: validate.TypeString, + Required: true, + Regexp: `[a-z,A-Z,0-9,-,.]`, + MinValueLength: 1, + MaxValueLength: 256, + }, + validate.ValidateSchema{ + Identifier: "target_instance_crn", + ValidateFunctionIdentifier: validate.ValidateRegexpLen, + Type: validate.TypeString, + Required: true, + Regexp: `[a-z,A-Z,0-9,:,-]`, + MinValueLength: 1, + MaxValueLength: 256, + }, + validate.ValidateSchema{ + Identifier: "access_credential", + ValidateFunctionIdentifier: validate.ValidateRegexpLen, + Type: validate.TypeString, + Required: true, + Regexp: `[a-z,A-Z,0-9,-\\.;!?]`, + MinValueLength: 10, + MaxValueLength: 50, + }, + ) + + resourceValidator := validate.ResourceValidator{ResourceName: "ibm_logs_router_tenant", Schema: validateSchema} + return &resourceValidator +} + +func resourceIbmLogsRouterTenantCreate(context context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + ibmLogsRouterOpenApi30Client, err := meta.(conns.ClientSession).IbmLogsRouterOpenApi30V0() + if err != nil { + return diag.FromErr(err) + } + + createTenantOptions := &ibmlogsrouteropenapi30v0.CreateTenantOptions{} + + createTenantOptions.SetTargetType(d.Get("target_type").(string)) + createTenantOptions.SetTargetHost(d.Get("target_host").(string)) + createTenantOptions.SetTargetPort(int64(d.Get("target_port").(int))) + createTenantOptions.SetAccessCredential(d.Get("access_credential").(string)) + createTenantOptions.SetTargetInstanceCrn(d.Get("target_instance_crn").(string)) + + tenantDetailsResponse, response, err := ibmLogsRouterOpenApi30Client.CreateTenantWithContext(context, createTenantOptions) + if err != nil { + log.Printf("[DEBUG] CreateTenantWithContext failed %s\n%s", err, response) + return diag.FromErr(fmt.Errorf("CreateTenantWithContext failed %s\n%s", err, response)) + } + + d.SetId(tenantDetailsResponse.ID.String()) + + return resourceIbmLogsRouterTenantRead(context, d, meta) +} + +func resourceIbmLogsRouterTenantRead(context context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + ibmLogsRouterOpenApi30Client, err := meta.(conns.ClientSession).IbmLogsRouterOpenApi30V0() + if err != nil { + return diag.FromErr(err) + } + + getTenantDetailOptions := &ibmlogsrouteropenapi30v0.GetTenantDetailOptions{} + tenantId := strfmt.UUID(d.Id()) + getTenantDetailOptions.SetTenantID(&tenantId) + + tenantDetailsResponse, response, err := ibmLogsRouterOpenApi30Client.GetTenantDetailWithContext(context, getTenantDetailOptions) + if err != nil { + if response != nil && response.StatusCode == 404 { + d.SetId("") + return nil + } + log.Printf("[DEBUG] GetTenantDetailWithContext failed %s\n%s", err, response) + return diag.FromErr(fmt.Errorf("GetTenantDetailWithContext failed %s\n%s", err, response)) + } + + if err = d.Set("target_type", tenantDetailsResponse.TargetType); err != nil { + return diag.FromErr(fmt.Errorf("Error setting target_type: %s", err)) + } + if err = d.Set("target_host", tenantDetailsResponse.TargetHost); err != nil { + return diag.FromErr(fmt.Errorf("Error setting target_host: %s", err)) + } + if err = d.Set("target_port", flex.IntValue(tenantDetailsResponse.TargetPort)); err != nil { + return diag.FromErr(fmt.Errorf("Error setting target_port: %s", err)) + } + if err = d.Set("target_instance_crn", tenantDetailsResponse.TargetInstanceCrn); err != nil { + return diag.FromErr(fmt.Errorf("Error setting target_instance_crn: %s", err)) + } + if !core.IsNil(tenantDetailsResponse.AccountID) { + if err = d.Set("account_id", tenantDetailsResponse.AccountID); err != nil { + return diag.FromErr(fmt.Errorf("Error setting account_id: %s", err)) + } + } + if !core.IsNil(tenantDetailsResponse.CreatedAt) { + if err = d.Set("created_at", tenantDetailsResponse.CreatedAt); err != nil { + return diag.FromErr(fmt.Errorf("Error setting created_at: %s", err)) + } + } + if !core.IsNil(tenantDetailsResponse.UpdatedAt) { + if err = d.Set("updated_at", tenantDetailsResponse.UpdatedAt); err != nil { + return diag.FromErr(fmt.Errorf("Error setting updated_at: %s", err)) + } + } + + return nil +} + +func resourceIbmLogsRouterTenantUpdate(context context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + ibmLogsRouterOpenApi30Client, err := meta.(conns.ClientSession).IbmLogsRouterOpenApi30V0() + if err != nil { + return diag.FromErr(err) + } + + updateTargetOptions := &ibmlogsrouteropenapi30v0.UpdateTargetOptions{} + tenantId := strfmt.UUID(d.Id()) + updateTargetOptions.SetTenantID(&tenantId) + + hasChange := false + + patchVals := &ibmlogsrouteropenapi30v0.TenantDetailsResponsePatch{} + if d.HasChange("target_host") { + newTargetHost := d.Get("target_host").(string) + patchVals.TargetHost = &newTargetHost + hasChange = true + } + if d.HasChange("target_port") { + newTargetPort := int64(d.Get("target_port").(int)) + patchVals.TargetPort = &newTargetPort + hasChange = true + } + if d.HasChange("access_credential") { + newAccessCredential := d.Get("access_credential").(string) + patchVals.AccessCredential = &newAccessCredential + hasChange = true + } + if d.HasChange("target_instance_crn") { + newTargetInstanceCrn := d.Get("target_instance_crn").(string) + patchVals.TargetInstanceCrn = &newTargetInstanceCrn + hasChange = true + } + + if hasChange { + updateTargetOptions.TenantDetailsResponsePatch, _ = patchVals.AsPatch() + _, response, err := ibmLogsRouterOpenApi30Client.UpdateTargetWithContext(context, updateTargetOptions) + if err != nil { + log.Printf("[DEBUG] UpdateTargetWithContext failed %s\n%s", err, response) + return diag.FromErr(fmt.Errorf("UpdateTargetWithContext failed %s\n%s", err, response)) + } + } + + return resourceIbmLogsRouterTenantRead(context, d, meta) +} + +func resourceIbmLogsRouterTenantDelete(context context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + ibmLogsRouterOpenApi30Client, err := meta.(conns.ClientSession).IbmLogsRouterOpenApi30V0() + if err != nil { + return diag.FromErr(err) + } + + deleteTenantOptions := &ibmlogsrouteropenapi30v0.DeleteTenantOptions{} + tenantId := strfmt.UUID(d.Id()) + deleteTenantOptions.SetTenantID(&tenantId) + + _, response, err := ibmLogsRouterOpenApi30Client.DeleteTenantWithContext(context, deleteTenantOptions) + if err != nil { + log.Printf("[DEBUG] DeleteTenantWithContext failed %s\n%s", err, response) + return diag.FromErr(fmt.Errorf("DeleteTenantWithContext failed %s\n%s", err, response)) + } + + d.SetId("") + + return nil +} diff --git a/ibm/service/logsrouter/resource_ibm_logs_router_tenant_test.go b/ibm/service/logsrouter/resource_ibm_logs_router_tenant_test.go new file mode 100644 index 0000000000..a625776d49 --- /dev/null +++ b/ibm/service/logsrouter/resource_ibm_logs_router_tenant_test.go @@ -0,0 +1,128 @@ +// Copyright IBM Corp. 2023 All Rights Reserved. +// Licensed under the Mozilla Public License v2.0 + +package logsrouter_test + +import ( + "fmt" + "testing" + + "github.com/go-openapi/strfmt" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + + acc "github.com/IBM-Cloud/terraform-provider-ibm/ibm/acctest" + "github.com/IBM-Cloud/terraform-provider-ibm/ibm/conns" + "github.com/IBM/logs-router-go-sdk/ibmlogsrouteropenapi30v0" +) + +func TestAccIbmLogsRouterTenantBasic(t *testing.T) { + var conf ibmlogsrouteropenapi30v0.TenantDetailsResponse + targetType := fmt.Sprintf("logdna") + targetHost := fmt.Sprintf("tf-target-host-%d", acctest.RandIntRange(10, 100)) + targetPort := fmt.Sprintf("%d", acctest.RandIntRange(10, 100)) + targetInstanceCrn := fmt.Sprintf("crn:v1:bluemix:public:logdna:eu-de:a/3516b8fa0a174a71899f5affa4f18d78:3517d2ed-9429-af34-ad52-34278391cbc8::") + targetTypeUpdate := fmt.Sprintf("logdna") + targetHostUpdate := fmt.Sprintf("tf-target-host-%d", acctest.RandIntRange(10, 100)) + targetPortUpdate := fmt.Sprintf("%d", acctest.RandIntRange(10, 100)) + targetInstanceCrnUpdate := fmt.Sprintf("crn:v1:bluemix:public:logdna:eu-de:a/3516b8fa0a174a71899f5affa4f18d78:3517d2ed-9429-af34-ad52-34278391cbc8::") + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acc.TestAccPreCheck(t) }, + Providers: acc.TestAccProviders, + CheckDestroy: testAccCheckIbmLogsRouterTenantDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccCheckIbmLogsRouterTenantConfigBasic(targetType, targetHost, targetPort, targetInstanceCrn), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckIbmLogsRouterTenantExists("ibm_logs_router_tenant.logs_router_tenant_instance", conf), + resource.TestCheckResourceAttr("ibm_logs_router_tenant.logs_router_tenant_instance", "target_type", targetType), + resource.TestCheckResourceAttr("ibm_logs_router_tenant.logs_router_tenant_instance", "target_host", targetHost), + resource.TestCheckResourceAttr("ibm_logs_router_tenant.logs_router_tenant_instance", "target_instance_crn", targetInstanceCrn), + ), + }, + resource.TestStep{ + Config: testAccCheckIbmLogsRouterTenantConfigBasic(targetTypeUpdate, targetHostUpdate, targetPortUpdate, targetInstanceCrnUpdate), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("ibm_logs_router_tenant.logs_router_tenant_instance", "target_type", targetTypeUpdate), + resource.TestCheckResourceAttr("ibm_logs_router_tenant.logs_router_tenant_instance", "target_host", targetHostUpdate), + resource.TestCheckResourceAttr("ibm_logs_router_tenant.logs_router_tenant_instance", "target_port", targetPortUpdate), + resource.TestCheckResourceAttr("ibm_logs_router_tenant.logs_router_tenant_instance", "target_instance_crn", targetInstanceCrnUpdate), + ), + }, + resource.TestStep{ + ResourceName: "ibm_logs_router_tenant.logs_router_tenant_instance", //"ibm_logs_router_tenant.logs_router_tenant", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"access_credential"}, + }, + }, + }) +} + +func testAccCheckIbmLogsRouterTenantConfigBasic(targetType string, targetHost string, targetPort string, targetInstanceCrn string) string { + return fmt.Sprintf(` + resource "ibm_logs_router_tenant" "logs_router_tenant_instance" { + target_type = "%s" + target_host = "%s" + target_port = %s + target_instance_crn = "%s" + access_credential = "test-credential" + } + `, targetType, targetHost, targetPort, targetInstanceCrn) +} + +func testAccCheckIbmLogsRouterTenantExists(n string, obj ibmlogsrouteropenapi30v0.TenantDetailsResponse) resource.TestCheckFunc { + + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found: %s", n) + } + + ibmLogsRouterOpenApi30Client, err := acc.TestAccProvider.Meta().(conns.ClientSession).IbmLogsRouterOpenApi30V0() + if err != nil { + return err + } + + getTenantDetailOptions := &ibmlogsrouteropenapi30v0.GetTenantDetailOptions{} + tenantId := strfmt.UUID(rs.Primary.ID) + getTenantDetailOptions.SetTenantID(&tenantId) + + tenantDetailsResponse, _, err := ibmLogsRouterOpenApi30Client.GetTenantDetail(getTenantDetailOptions) + if err != nil { + return err + } + + obj = *tenantDetailsResponse + return nil + } +} + +func testAccCheckIbmLogsRouterTenantDestroy(s *terraform.State) error { + ibmLogsRouterOpenApi30Client, err := acc.TestAccProvider.Meta().(conns.ClientSession).IbmLogsRouterOpenApi30V0() + if err != nil { + return err + } + for _, rs := range s.RootModule().Resources { + if rs.Type != "ibm_logs_router_tenant" { + continue + } + + getTenantDetailOptions := &ibmlogsrouteropenapi30v0.GetTenantDetailOptions{} + tenantId := strfmt.UUID(rs.Primary.ID) + getTenantDetailOptions.SetTenantID(&tenantId) + + // Try to find the key + _, response, err := ibmLogsRouterOpenApi30Client.GetTenantDetail(getTenantDetailOptions) + + if err == nil { + return fmt.Errorf("logs_router_tenant still exists: %s", rs.Primary.ID) + } else if response.StatusCode != 404 { + return fmt.Errorf("Error checking for logs_router_tenant (%s) has been destroyed: %s", rs.Primary.ID, err) + } + } + + return nil +} diff --git a/website/allowed-subcategories.txt b/website/allowed-subcategories.txt index 1e97423139..7410d43146 100644 --- a/website/allowed-subcategories.txt +++ b/website/allowed-subcategories.txt @@ -25,6 +25,7 @@ Identity & Access Management (IAM) Internet services Key Management Service Kubernetes Service +Logs Router Metrics Router Object Storage Power Systems diff --git a/website/docs/d/logs_router_tenant.html.markdown b/website/docs/d/logs_router_tenant.html.markdown new file mode 100644 index 0000000000..0ff47b87b3 --- /dev/null +++ b/website/docs/d/logs_router_tenant.html.markdown @@ -0,0 +1,52 @@ +--- +layout: "ibm" +page_title: "IBM : ibm_logs_router_tenant" +description: |- + Get information about logs_router_tenant +subcategory: "Logs Router" +--- + +# ibm_logs_router_tenant + +Provides a read-only data source to retrieve information about a logs_router_tenant. You can then reference the fields of the data source in other resources within the same configuration by using interpolation syntax. + +## Example Usage + +```hcl +data "ibm_logs_router_tenant" "logs_router_tenant" { + tenant_id = "f3a466c9-c4db-4eee-95cc-ba82db58e2b5" +} +``` + +## Argument Reference + +You can specify the following arguments for this data source. + +* `tenant_id` - (Required, Forces new resource, String) The instance ID of the tenant. + * Constraints: The maximum length is `36` characters. The minimum length is `36` characters. The value must match regular expression `/[A-F,0-9,-]/`. + +## Attribute Reference + +After your data source is created, you can read values from the following attributes. + +* `id` - The unique identifier of the logs_router_tenant. +* `account_id` - (String) The account ID the tenant belongs to. + * Constraints: The maximum length is `32` characters. The minimum length is `32` characters. The value must match regular expression `/[a-z,A-Z,0-9,-]/`. + +* `created_at` - (String) Time stamp the tenant was originally created. + * Constraints: The maximum length is `36` characters. The minimum length is `1` character. The value must match regular expression `/[0-9,:,.,-,T,Z]/`. + +* `target_host` - (String) Host name of log-sink. + * Constraints: The maximum length is `256` characters. The minimum length is `1` character. The value must match regular expression `/[a-z,A-Z,0-9,-,.]/`. + +* `target_instance_crn` - (String) Cloud resource name of the log-sink target instance. + * Constraints: The maximum length is `256` characters. The minimum length is `1` character. The value must match regular expression `/[a-z,A-Z,0-9,:,-]/`. + +* `target_port` - (Integer) Network port of log sink. + +* `target_type` - (String) Type of log-sink. + * Constraints: The maximum length is `32` characters. The minimum length is `1` character. The value must match regular expression `/[a-z,A-Z,0-9,-]/`. + +* `updated_at` - (String) time stamp the tenant was last updated. + * Constraints: The maximum length is `36` characters. The minimum length is `1` character. The value must match regular expression `/[0-9,:,.,-,T,Z]/`. + diff --git a/website/docs/r/logs_router_tenant.html.markdown b/website/docs/r/logs_router_tenant.html.markdown new file mode 100644 index 0000000000..0a193468d8 --- /dev/null +++ b/website/docs/r/logs_router_tenant.html.markdown @@ -0,0 +1,60 @@ +--- +layout: "ibm" +page_title: "IBM : ibm_logs_router_tenant" +description: |- + Manages logs_router_tenant. +subcategory: "Logs Router" +--- + +# ibm_logs_router_tenant + +Create, update, and delete logs_router_tenants with this resource. + +## Example Usage + +```hcl +resource "ibm_logs_router_tenant" "logs_router_tenant_instance" { + target_host = "www.example.com" + target_instance_crn = "crn:v1:bluemix:public:logdna:eu-de:a/3516b8fa0a174a71899f5affa4f18d78:3517d2ed-9429-af34-ad52-34278391cbc8::" + target_port = 10 + target_type = "logdna" +} +``` + +## Argument Reference + +You can specify the following arguments for this resource. + +* `target_host` - (Required, String) Host name of log-sink. + * Constraints: The maximum length is `256` characters. The minimum length is `1` character. The value must match regular expression `/[a-z,A-Z,0-9,-,.]/`. +* `target_instance_crn` - (Required, String) Cloud resource name of the log-sink target instance. + * Constraints: The maximum length is `256` characters. The minimum length is `1` character. The value must match regular expression `/[a-z,A-Z,0-9,:,-]/`. +* `target_port` - (Required, Integer) Network port of log sink. +* `target_type` - (Required, String) Type of log-sink. + * Constraints: The maximum length is `32` characters. The minimum length is `1` character. The value must match regular expression `/[a-z,A-Z,0-9,-]/`. + +## Attribute Reference + +After your resource is created, you can read values from the listed arguments and the following attributes. + +* `id` - The unique identifier of the logs_router_tenant. +* `account_id` - (String) The account ID the tenant belongs to. + * Constraints: The maximum length is `32` characters. The minimum length is `32` characters. The value must match regular expression `/[a-z,A-Z,0-9,-]/`. +* `created_at` - (String) Time stamp the tenant was originally created. + * Constraints: The maximum length is `36` characters. The minimum length is `1` character. The value must match regular expression `/[0-9,:,.,-,T,Z]/`. +* `updated_at` - (String) time stamp the tenant was last updated. + * Constraints: The maximum length is `36` characters. The minimum length is `1` character. The value must match regular expression `/[0-9,:,.,-,T,Z]/`. + +## Import + +You can import the `ibm_logs_router_tenant` resource by using `id`. Unique ID of the created instance. + +# Syntax +
+$ terraform import ibm_logs_router_tenant.logs_router_tenant <id>
+
+ +# Example +``` +$ terraform import ibm_logs_router_tenant.logs_router_tenant aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa +```