diff --git a/google/config.go b/google/config.go index dcd689dee83..c5da8d81cea 100644 --- a/google/config.go +++ b/google/config.go @@ -90,6 +90,7 @@ type Config struct { FilestoreBasePath string FirestoreBasePath string IapBasePath string + IdentityPlatformBasePath string KMSBasePath string LoggingBasePath string MLEngineBasePath string @@ -220,6 +221,7 @@ var DNSDefaultBasePath = "https://www.googleapis.com/dns/v1/" var FilestoreDefaultBasePath = "https://file.googleapis.com/v1/" var FirestoreDefaultBasePath = "https://firestore.googleapis.com/v1/" var IapDefaultBasePath = "https://iap.googleapis.com/v1/" +var IdentityPlatformDefaultBasePath = "https://identitytoolkit.googleapis.com/v2/" var KMSDefaultBasePath = "https://cloudkms.googleapis.com/v1/" var LoggingDefaultBasePath = "https://logging.googleapis.com/v2/" var MLEngineDefaultBasePath = "https://ml.googleapis.com/v1/" @@ -694,6 +696,7 @@ func ConfigureBasePaths(c *Config) { c.FilestoreBasePath = FilestoreDefaultBasePath c.FirestoreBasePath = FirestoreDefaultBasePath c.IapBasePath = IapDefaultBasePath + c.IdentityPlatformBasePath = IdentityPlatformDefaultBasePath c.KMSBasePath = KMSDefaultBasePath c.LoggingBasePath = LoggingDefaultBasePath c.MLEngineBasePath = MLEngineDefaultBasePath diff --git a/google/provider.go b/google/provider.go index 69df00416ae..c9bc80abae0 100644 --- a/google/provider.go +++ b/google/provider.go @@ -261,6 +261,14 @@ func Provider() terraform.ResourceProvider { "GOOGLE_IAP_CUSTOM_ENDPOINT", }, IapDefaultBasePath), }, + "identity_platform_custom_endpoint": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validateCustomEndpoint, + DefaultFunc: schema.MultiEnvDefaultFunc([]string{ + "GOOGLE_IDENTITY_PLATFORM_CUSTOM_ENDPOINT", + }, IdentityPlatformDefaultBasePath), + }, "kms_custom_endpoint": { Type: schema.TypeString, Optional: true, @@ -468,9 +476,9 @@ func Provider() terraform.ResourceProvider { return provider } -// Generated resources: 88 +// Generated resources: 95 // Generated IAM resources: 45 -// Total generated resources: 133 +// Total generated resources: 140 func ResourceMap() map[string]*schema.Resource { resourceMap, _ := ResourceMapWithErrors() return resourceMap @@ -479,139 +487,146 @@ func ResourceMap() map[string]*schema.Resource { func ResourceMapWithErrors() (map[string]*schema.Resource, error) { return mergeResourceMaps( map[string]*schema.Resource{ - "google_access_context_manager_access_policy": resourceAccessContextManagerAccessPolicy(), - "google_access_context_manager_access_level": resourceAccessContextManagerAccessLevel(), - "google_access_context_manager_service_perimeter": resourceAccessContextManagerServicePerimeter(), - "google_app_engine_domain_mapping": resourceAppEngineDomainMapping(), - "google_app_engine_firewall_rule": resourceAppEngineFirewallRule(), - "google_app_engine_standard_app_version": resourceAppEngineStandardAppVersion(), - "google_app_engine_application_url_dispatch_rules": resourceAppEngineApplicationUrlDispatchRules(), - "google_bigquery_dataset": resourceBigQueryDataset(), - "google_bigquery_data_transfer_config": resourceBigqueryDataTransferConfig(), - "google_bigtable_app_profile": resourceBigtableAppProfile(), - "google_binary_authorization_attestor": resourceBinaryAuthorizationAttestor(), - "google_binary_authorization_attestor_iam_binding": ResourceIamBinding(BinaryAuthorizationAttestorIamSchema, BinaryAuthorizationAttestorIamUpdaterProducer, BinaryAuthorizationAttestorIdParseFunc), - "google_binary_authorization_attestor_iam_member": ResourceIamMember(BinaryAuthorizationAttestorIamSchema, BinaryAuthorizationAttestorIamUpdaterProducer, BinaryAuthorizationAttestorIdParseFunc), - "google_binary_authorization_attestor_iam_policy": ResourceIamPolicy(BinaryAuthorizationAttestorIamSchema, BinaryAuthorizationAttestorIamUpdaterProducer, BinaryAuthorizationAttestorIdParseFunc), - "google_binary_authorization_policy": resourceBinaryAuthorizationPolicy(), - "google_cloudbuild_trigger": resourceCloudBuildTrigger(), - "google_cloudfunctions_function_iam_binding": ResourceIamBinding(CloudFunctionsCloudFunctionIamSchema, CloudFunctionsCloudFunctionIamUpdaterProducer, CloudFunctionsCloudFunctionIdParseFunc), - "google_cloudfunctions_function_iam_member": ResourceIamMember(CloudFunctionsCloudFunctionIamSchema, CloudFunctionsCloudFunctionIamUpdaterProducer, CloudFunctionsCloudFunctionIdParseFunc), - "google_cloudfunctions_function_iam_policy": ResourceIamPolicy(CloudFunctionsCloudFunctionIamSchema, CloudFunctionsCloudFunctionIamUpdaterProducer, CloudFunctionsCloudFunctionIdParseFunc), - "google_cloud_run_domain_mapping": resourceCloudRunDomainMapping(), - "google_cloud_run_service": resourceCloudRunService(), - "google_cloud_run_service_iam_binding": ResourceIamBinding(CloudRunServiceIamSchema, CloudRunServiceIamUpdaterProducer, CloudRunServiceIdParseFunc), - "google_cloud_run_service_iam_member": ResourceIamMember(CloudRunServiceIamSchema, CloudRunServiceIamUpdaterProducer, CloudRunServiceIdParseFunc), - "google_cloud_run_service_iam_policy": ResourceIamPolicy(CloudRunServiceIamSchema, CloudRunServiceIamUpdaterProducer, CloudRunServiceIdParseFunc), - "google_cloud_scheduler_job": resourceCloudSchedulerJob(), - "google_cloud_tasks_queue": resourceCloudTasksQueue(), - "google_compute_address": resourceComputeAddress(), - "google_compute_autoscaler": resourceComputeAutoscaler(), - "google_compute_backend_bucket": resourceComputeBackendBucket(), - "google_compute_backend_bucket_signed_url_key": resourceComputeBackendBucketSignedUrlKey(), - "google_compute_backend_service": resourceComputeBackendService(), - "google_compute_region_backend_service": resourceComputeRegionBackendService(), - "google_compute_backend_service_signed_url_key": resourceComputeBackendServiceSignedUrlKey(), - "google_compute_disk_resource_policy_attachment": resourceComputeDiskResourcePolicyAttachment(), - "google_compute_disk": resourceComputeDisk(), - "google_compute_firewall": resourceComputeFirewall(), - "google_compute_forwarding_rule": resourceComputeForwardingRule(), - "google_compute_global_address": resourceComputeGlobalAddress(), - "google_compute_global_forwarding_rule": resourceComputeGlobalForwardingRule(), - "google_compute_http_health_check": resourceComputeHttpHealthCheck(), - "google_compute_https_health_check": resourceComputeHttpsHealthCheck(), - "google_compute_health_check": resourceComputeHealthCheck(), - "google_compute_image": resourceComputeImage(), - "google_compute_instance_iam_binding": ResourceIamBinding(ComputeInstanceIamSchema, ComputeInstanceIamUpdaterProducer, ComputeInstanceIdParseFunc), - "google_compute_instance_iam_member": ResourceIamMember(ComputeInstanceIamSchema, ComputeInstanceIamUpdaterProducer, ComputeInstanceIdParseFunc), - "google_compute_instance_iam_policy": ResourceIamPolicy(ComputeInstanceIamSchema, ComputeInstanceIamUpdaterProducer, ComputeInstanceIdParseFunc), - "google_compute_interconnect_attachment": resourceComputeInterconnectAttachment(), - "google_compute_network": resourceComputeNetwork(), - "google_compute_network_endpoint": resourceComputeNetworkEndpoint(), - "google_compute_network_endpoint_group": resourceComputeNetworkEndpointGroup(), - "google_compute_node_group": resourceComputeNodeGroup(), - "google_compute_node_template": resourceComputeNodeTemplate(), - "google_compute_region_autoscaler": resourceComputeRegionAutoscaler(), - "google_compute_region_disk": resourceComputeRegionDisk(), - "google_compute_region_health_check": resourceComputeRegionHealthCheck(), - "google_compute_resource_policy": resourceComputeResourcePolicy(), - "google_compute_route": resourceComputeRoute(), - "google_compute_router": resourceComputeRouter(), - "google_compute_router_nat": resourceComputeRouterNat(), - "google_compute_router_peer": resourceComputeRouterBgpPeer(), - "google_compute_snapshot": resourceComputeSnapshot(), - "google_compute_ssl_certificate": resourceComputeSslCertificate(), - "google_compute_reservation": resourceComputeReservation(), - "google_compute_ssl_policy": resourceComputeSslPolicy(), - "google_compute_subnetwork": resourceComputeSubnetwork(), - "google_compute_subnetwork_iam_binding": ResourceIamBinding(ComputeSubnetworkIamSchema, ComputeSubnetworkIamUpdaterProducer, ComputeSubnetworkIdParseFunc), - "google_compute_subnetwork_iam_member": ResourceIamMember(ComputeSubnetworkIamSchema, ComputeSubnetworkIamUpdaterProducer, ComputeSubnetworkIdParseFunc), - "google_compute_subnetwork_iam_policy": ResourceIamPolicy(ComputeSubnetworkIamSchema, ComputeSubnetworkIamUpdaterProducer, ComputeSubnetworkIdParseFunc), - "google_compute_target_http_proxy": resourceComputeTargetHttpProxy(), - "google_compute_target_https_proxy": resourceComputeTargetHttpsProxy(), - "google_compute_target_instance": resourceComputeTargetInstance(), - "google_compute_target_ssl_proxy": resourceComputeTargetSslProxy(), - "google_compute_target_tcp_proxy": resourceComputeTargetTcpProxy(), - "google_compute_vpn_gateway": resourceComputeVpnGateway(), - "google_compute_url_map": resourceComputeUrlMap(), - "google_compute_vpn_tunnel": resourceComputeVpnTunnel(), - "google_container_analysis_note": resourceContainerAnalysisNote(), - "google_dataproc_autoscaling_policy": resourceDataprocAutoscalingPolicy(), - "google_deployment_manager_deployment": resourceDeploymentManagerDeployment(), - "google_dns_managed_zone": resourceDNSManagedZone(), - "google_filestore_instance": resourceFilestoreInstance(), - "google_firestore_index": resourceFirestoreIndex(), - "google_iap_web_iam_binding": ResourceIamBinding(IapWebIamSchema, IapWebIamUpdaterProducer, IapWebIdParseFunc), - "google_iap_web_iam_member": ResourceIamMember(IapWebIamSchema, IapWebIamUpdaterProducer, IapWebIdParseFunc), - "google_iap_web_iam_policy": ResourceIamPolicy(IapWebIamSchema, IapWebIamUpdaterProducer, IapWebIdParseFunc), - "google_iap_web_type_compute_iam_binding": ResourceIamBinding(IapWebTypeComputeIamSchema, IapWebTypeComputeIamUpdaterProducer, IapWebTypeComputeIdParseFunc), - "google_iap_web_type_compute_iam_member": ResourceIamMember(IapWebTypeComputeIamSchema, IapWebTypeComputeIamUpdaterProducer, IapWebTypeComputeIdParseFunc), - "google_iap_web_type_compute_iam_policy": ResourceIamPolicy(IapWebTypeComputeIamSchema, IapWebTypeComputeIamUpdaterProducer, IapWebTypeComputeIdParseFunc), - "google_iap_web_type_app_engine_iam_binding": ResourceIamBinding(IapWebTypeAppEngineIamSchema, IapWebTypeAppEngineIamUpdaterProducer, IapWebTypeAppEngineIdParseFunc), - "google_iap_web_type_app_engine_iam_member": ResourceIamMember(IapWebTypeAppEngineIamSchema, IapWebTypeAppEngineIamUpdaterProducer, IapWebTypeAppEngineIdParseFunc), - "google_iap_web_type_app_engine_iam_policy": ResourceIamPolicy(IapWebTypeAppEngineIamSchema, IapWebTypeAppEngineIamUpdaterProducer, IapWebTypeAppEngineIdParseFunc), - "google_iap_app_engine_version_iam_binding": ResourceIamBinding(IapAppEngineVersionIamSchema, IapAppEngineVersionIamUpdaterProducer, IapAppEngineVersionIdParseFunc), - "google_iap_app_engine_version_iam_member": ResourceIamMember(IapAppEngineVersionIamSchema, IapAppEngineVersionIamUpdaterProducer, IapAppEngineVersionIdParseFunc), - "google_iap_app_engine_version_iam_policy": ResourceIamPolicy(IapAppEngineVersionIamSchema, IapAppEngineVersionIamUpdaterProducer, IapAppEngineVersionIdParseFunc), - "google_iap_app_engine_service_iam_binding": ResourceIamBinding(IapAppEngineServiceIamSchema, IapAppEngineServiceIamUpdaterProducer, IapAppEngineServiceIdParseFunc), - "google_iap_app_engine_service_iam_member": ResourceIamMember(IapAppEngineServiceIamSchema, IapAppEngineServiceIamUpdaterProducer, IapAppEngineServiceIdParseFunc), - "google_iap_app_engine_service_iam_policy": ResourceIamPolicy(IapAppEngineServiceIamSchema, IapAppEngineServiceIamUpdaterProducer, IapAppEngineServiceIdParseFunc), - "google_iap_web_backend_service_iam_binding": ResourceIamBinding(IapWebBackendServiceIamSchema, IapWebBackendServiceIamUpdaterProducer, IapWebBackendServiceIdParseFunc), - "google_iap_web_backend_service_iam_member": ResourceIamMember(IapWebBackendServiceIamSchema, IapWebBackendServiceIamUpdaterProducer, IapWebBackendServiceIdParseFunc), - "google_iap_web_backend_service_iam_policy": ResourceIamPolicy(IapWebBackendServiceIamSchema, IapWebBackendServiceIamUpdaterProducer, IapWebBackendServiceIdParseFunc), - "google_kms_key_ring": resourceKMSKeyRing(), - "google_kms_crypto_key": resourceKMSCryptoKey(), - "google_logging_metric": resourceLoggingMetric(), - "google_ml_engine_model": resourceMLEngineModel(), - "google_monitoring_alert_policy": resourceMonitoringAlertPolicy(), - "google_monitoring_group": resourceMonitoringGroup(), - "google_monitoring_notification_channel": resourceMonitoringNotificationChannel(), - "google_monitoring_uptime_check_config": resourceMonitoringUptimeCheckConfig(), - "google_pubsub_topic": resourcePubsubTopic(), - "google_pubsub_topic_iam_binding": ResourceIamBinding(PubsubTopicIamSchema, PubsubTopicIamUpdaterProducer, PubsubTopicIdParseFunc), - "google_pubsub_topic_iam_member": ResourceIamMember(PubsubTopicIamSchema, PubsubTopicIamUpdaterProducer, PubsubTopicIdParseFunc), - "google_pubsub_topic_iam_policy": ResourceIamPolicy(PubsubTopicIamSchema, PubsubTopicIamUpdaterProducer, PubsubTopicIdParseFunc), - "google_pubsub_subscription": resourcePubsubSubscription(), - "google_redis_instance": resourceRedisInstance(), - "google_resource_manager_lien": resourceResourceManagerLien(), - "google_runtimeconfig_config_iam_binding": ResourceIamBinding(RuntimeConfigConfigIamSchema, RuntimeConfigConfigIamUpdaterProducer, RuntimeConfigConfigIdParseFunc), - "google_runtimeconfig_config_iam_member": ResourceIamMember(RuntimeConfigConfigIamSchema, RuntimeConfigConfigIamUpdaterProducer, RuntimeConfigConfigIdParseFunc), - "google_runtimeconfig_config_iam_policy": ResourceIamPolicy(RuntimeConfigConfigIamSchema, RuntimeConfigConfigIamUpdaterProducer, RuntimeConfigConfigIdParseFunc), - "google_scc_source": resourceSecurityCenterSource(), - "google_sourcerepo_repository": resourceSourceRepoRepository(), - "google_sourcerepo_repository_iam_binding": ResourceIamBinding(SourceRepoRepositoryIamSchema, SourceRepoRepositoryIamUpdaterProducer, SourceRepoRepositoryIdParseFunc), - "google_sourcerepo_repository_iam_member": ResourceIamMember(SourceRepoRepositoryIamSchema, SourceRepoRepositoryIamUpdaterProducer, SourceRepoRepositoryIdParseFunc), - "google_sourcerepo_repository_iam_policy": ResourceIamPolicy(SourceRepoRepositoryIamSchema, SourceRepoRepositoryIamUpdaterProducer, SourceRepoRepositoryIdParseFunc), - "google_spanner_instance": resourceSpannerInstance(), - "google_spanner_database": resourceSpannerDatabase(), - "google_sql_database": resourceSQLDatabase(), - "google_storage_bucket_iam_binding": ResourceIamBinding(StorageBucketIamSchema, StorageBucketIamUpdaterProducer, StorageBucketIdParseFunc), - "google_storage_bucket_iam_member": ResourceIamMember(StorageBucketIamSchema, StorageBucketIamUpdaterProducer, StorageBucketIdParseFunc), - "google_storage_bucket_iam_policy": ResourceIamPolicy(StorageBucketIamSchema, StorageBucketIamUpdaterProducer, StorageBucketIdParseFunc), - "google_storage_bucket_access_control": resourceStorageBucketAccessControl(), - "google_storage_object_access_control": resourceStorageObjectAccessControl(), - "google_storage_default_object_access_control": resourceStorageDefaultObjectAccessControl(), - "google_tpu_node": resourceTPUNode(), + "google_access_context_manager_access_policy": resourceAccessContextManagerAccessPolicy(), + "google_access_context_manager_access_level": resourceAccessContextManagerAccessLevel(), + "google_access_context_manager_service_perimeter": resourceAccessContextManagerServicePerimeter(), + "google_app_engine_domain_mapping": resourceAppEngineDomainMapping(), + "google_app_engine_firewall_rule": resourceAppEngineFirewallRule(), + "google_app_engine_standard_app_version": resourceAppEngineStandardAppVersion(), + "google_app_engine_application_url_dispatch_rules": resourceAppEngineApplicationUrlDispatchRules(), + "google_bigquery_dataset": resourceBigQueryDataset(), + "google_bigquery_data_transfer_config": resourceBigqueryDataTransferConfig(), + "google_bigtable_app_profile": resourceBigtableAppProfile(), + "google_binary_authorization_attestor": resourceBinaryAuthorizationAttestor(), + "google_binary_authorization_attestor_iam_binding": ResourceIamBinding(BinaryAuthorizationAttestorIamSchema, BinaryAuthorizationAttestorIamUpdaterProducer, BinaryAuthorizationAttestorIdParseFunc), + "google_binary_authorization_attestor_iam_member": ResourceIamMember(BinaryAuthorizationAttestorIamSchema, BinaryAuthorizationAttestorIamUpdaterProducer, BinaryAuthorizationAttestorIdParseFunc), + "google_binary_authorization_attestor_iam_policy": ResourceIamPolicy(BinaryAuthorizationAttestorIamSchema, BinaryAuthorizationAttestorIamUpdaterProducer, BinaryAuthorizationAttestorIdParseFunc), + "google_binary_authorization_policy": resourceBinaryAuthorizationPolicy(), + "google_cloudbuild_trigger": resourceCloudBuildTrigger(), + "google_cloudfunctions_function_iam_binding": ResourceIamBinding(CloudFunctionsCloudFunctionIamSchema, CloudFunctionsCloudFunctionIamUpdaterProducer, CloudFunctionsCloudFunctionIdParseFunc), + "google_cloudfunctions_function_iam_member": ResourceIamMember(CloudFunctionsCloudFunctionIamSchema, CloudFunctionsCloudFunctionIamUpdaterProducer, CloudFunctionsCloudFunctionIdParseFunc), + "google_cloudfunctions_function_iam_policy": ResourceIamPolicy(CloudFunctionsCloudFunctionIamSchema, CloudFunctionsCloudFunctionIamUpdaterProducer, CloudFunctionsCloudFunctionIdParseFunc), + "google_cloud_run_domain_mapping": resourceCloudRunDomainMapping(), + "google_cloud_run_service": resourceCloudRunService(), + "google_cloud_run_service_iam_binding": ResourceIamBinding(CloudRunServiceIamSchema, CloudRunServiceIamUpdaterProducer, CloudRunServiceIdParseFunc), + "google_cloud_run_service_iam_member": ResourceIamMember(CloudRunServiceIamSchema, CloudRunServiceIamUpdaterProducer, CloudRunServiceIdParseFunc), + "google_cloud_run_service_iam_policy": ResourceIamPolicy(CloudRunServiceIamSchema, CloudRunServiceIamUpdaterProducer, CloudRunServiceIdParseFunc), + "google_cloud_scheduler_job": resourceCloudSchedulerJob(), + "google_cloud_tasks_queue": resourceCloudTasksQueue(), + "google_compute_address": resourceComputeAddress(), + "google_compute_autoscaler": resourceComputeAutoscaler(), + "google_compute_backend_bucket": resourceComputeBackendBucket(), + "google_compute_backend_bucket_signed_url_key": resourceComputeBackendBucketSignedUrlKey(), + "google_compute_backend_service": resourceComputeBackendService(), + "google_compute_region_backend_service": resourceComputeRegionBackendService(), + "google_compute_backend_service_signed_url_key": resourceComputeBackendServiceSignedUrlKey(), + "google_compute_disk_resource_policy_attachment": resourceComputeDiskResourcePolicyAttachment(), + "google_compute_disk": resourceComputeDisk(), + "google_compute_firewall": resourceComputeFirewall(), + "google_compute_forwarding_rule": resourceComputeForwardingRule(), + "google_compute_global_address": resourceComputeGlobalAddress(), + "google_compute_global_forwarding_rule": resourceComputeGlobalForwardingRule(), + "google_compute_http_health_check": resourceComputeHttpHealthCheck(), + "google_compute_https_health_check": resourceComputeHttpsHealthCheck(), + "google_compute_health_check": resourceComputeHealthCheck(), + "google_compute_image": resourceComputeImage(), + "google_compute_instance_iam_binding": ResourceIamBinding(ComputeInstanceIamSchema, ComputeInstanceIamUpdaterProducer, ComputeInstanceIdParseFunc), + "google_compute_instance_iam_member": ResourceIamMember(ComputeInstanceIamSchema, ComputeInstanceIamUpdaterProducer, ComputeInstanceIdParseFunc), + "google_compute_instance_iam_policy": ResourceIamPolicy(ComputeInstanceIamSchema, ComputeInstanceIamUpdaterProducer, ComputeInstanceIdParseFunc), + "google_compute_interconnect_attachment": resourceComputeInterconnectAttachment(), + "google_compute_network": resourceComputeNetwork(), + "google_compute_network_endpoint": resourceComputeNetworkEndpoint(), + "google_compute_network_endpoint_group": resourceComputeNetworkEndpointGroup(), + "google_compute_node_group": resourceComputeNodeGroup(), + "google_compute_node_template": resourceComputeNodeTemplate(), + "google_compute_region_autoscaler": resourceComputeRegionAutoscaler(), + "google_compute_region_disk": resourceComputeRegionDisk(), + "google_compute_region_health_check": resourceComputeRegionHealthCheck(), + "google_compute_resource_policy": resourceComputeResourcePolicy(), + "google_compute_route": resourceComputeRoute(), + "google_compute_router": resourceComputeRouter(), + "google_compute_router_nat": resourceComputeRouterNat(), + "google_compute_router_peer": resourceComputeRouterBgpPeer(), + "google_compute_snapshot": resourceComputeSnapshot(), + "google_compute_ssl_certificate": resourceComputeSslCertificate(), + "google_compute_reservation": resourceComputeReservation(), + "google_compute_ssl_policy": resourceComputeSslPolicy(), + "google_compute_subnetwork": resourceComputeSubnetwork(), + "google_compute_subnetwork_iam_binding": ResourceIamBinding(ComputeSubnetworkIamSchema, ComputeSubnetworkIamUpdaterProducer, ComputeSubnetworkIdParseFunc), + "google_compute_subnetwork_iam_member": ResourceIamMember(ComputeSubnetworkIamSchema, ComputeSubnetworkIamUpdaterProducer, ComputeSubnetworkIdParseFunc), + "google_compute_subnetwork_iam_policy": ResourceIamPolicy(ComputeSubnetworkIamSchema, ComputeSubnetworkIamUpdaterProducer, ComputeSubnetworkIdParseFunc), + "google_compute_target_http_proxy": resourceComputeTargetHttpProxy(), + "google_compute_target_https_proxy": resourceComputeTargetHttpsProxy(), + "google_compute_target_instance": resourceComputeTargetInstance(), + "google_compute_target_ssl_proxy": resourceComputeTargetSslProxy(), + "google_compute_target_tcp_proxy": resourceComputeTargetTcpProxy(), + "google_compute_vpn_gateway": resourceComputeVpnGateway(), + "google_compute_url_map": resourceComputeUrlMap(), + "google_compute_vpn_tunnel": resourceComputeVpnTunnel(), + "google_container_analysis_note": resourceContainerAnalysisNote(), + "google_dataproc_autoscaling_policy": resourceDataprocAutoscalingPolicy(), + "google_deployment_manager_deployment": resourceDeploymentManagerDeployment(), + "google_dns_managed_zone": resourceDNSManagedZone(), + "google_filestore_instance": resourceFilestoreInstance(), + "google_firestore_index": resourceFirestoreIndex(), + "google_iap_web_iam_binding": ResourceIamBinding(IapWebIamSchema, IapWebIamUpdaterProducer, IapWebIdParseFunc), + "google_iap_web_iam_member": ResourceIamMember(IapWebIamSchema, IapWebIamUpdaterProducer, IapWebIdParseFunc), + "google_iap_web_iam_policy": ResourceIamPolicy(IapWebIamSchema, IapWebIamUpdaterProducer, IapWebIdParseFunc), + "google_iap_web_type_compute_iam_binding": ResourceIamBinding(IapWebTypeComputeIamSchema, IapWebTypeComputeIamUpdaterProducer, IapWebTypeComputeIdParseFunc), + "google_iap_web_type_compute_iam_member": ResourceIamMember(IapWebTypeComputeIamSchema, IapWebTypeComputeIamUpdaterProducer, IapWebTypeComputeIdParseFunc), + "google_iap_web_type_compute_iam_policy": ResourceIamPolicy(IapWebTypeComputeIamSchema, IapWebTypeComputeIamUpdaterProducer, IapWebTypeComputeIdParseFunc), + "google_iap_web_type_app_engine_iam_binding": ResourceIamBinding(IapWebTypeAppEngineIamSchema, IapWebTypeAppEngineIamUpdaterProducer, IapWebTypeAppEngineIdParseFunc), + "google_iap_web_type_app_engine_iam_member": ResourceIamMember(IapWebTypeAppEngineIamSchema, IapWebTypeAppEngineIamUpdaterProducer, IapWebTypeAppEngineIdParseFunc), + "google_iap_web_type_app_engine_iam_policy": ResourceIamPolicy(IapWebTypeAppEngineIamSchema, IapWebTypeAppEngineIamUpdaterProducer, IapWebTypeAppEngineIdParseFunc), + "google_iap_app_engine_version_iam_binding": ResourceIamBinding(IapAppEngineVersionIamSchema, IapAppEngineVersionIamUpdaterProducer, IapAppEngineVersionIdParseFunc), + "google_iap_app_engine_version_iam_member": ResourceIamMember(IapAppEngineVersionIamSchema, IapAppEngineVersionIamUpdaterProducer, IapAppEngineVersionIdParseFunc), + "google_iap_app_engine_version_iam_policy": ResourceIamPolicy(IapAppEngineVersionIamSchema, IapAppEngineVersionIamUpdaterProducer, IapAppEngineVersionIdParseFunc), + "google_iap_app_engine_service_iam_binding": ResourceIamBinding(IapAppEngineServiceIamSchema, IapAppEngineServiceIamUpdaterProducer, IapAppEngineServiceIdParseFunc), + "google_iap_app_engine_service_iam_member": ResourceIamMember(IapAppEngineServiceIamSchema, IapAppEngineServiceIamUpdaterProducer, IapAppEngineServiceIdParseFunc), + "google_iap_app_engine_service_iam_policy": ResourceIamPolicy(IapAppEngineServiceIamSchema, IapAppEngineServiceIamUpdaterProducer, IapAppEngineServiceIdParseFunc), + "google_iap_web_backend_service_iam_binding": ResourceIamBinding(IapWebBackendServiceIamSchema, IapWebBackendServiceIamUpdaterProducer, IapWebBackendServiceIdParseFunc), + "google_iap_web_backend_service_iam_member": ResourceIamMember(IapWebBackendServiceIamSchema, IapWebBackendServiceIamUpdaterProducer, IapWebBackendServiceIdParseFunc), + "google_iap_web_backend_service_iam_policy": ResourceIamPolicy(IapWebBackendServiceIamSchema, IapWebBackendServiceIamUpdaterProducer, IapWebBackendServiceIdParseFunc), + "google_identity_platform_default_supported_idp_config": resourceIdentityPlatformDefaultSupportedIdpConfig(), + "google_identity_platform_tenant_default_supported_idp_config": resourceIdentityPlatformTenantDefaultSupportedIdpConfig(), + "google_identity_platform_inbound_saml_config": resourceIdentityPlatformInboundSamlConfig(), + "google_identity_platform_tenant_inbound_saml_config": resourceIdentityPlatformTenantInboundSamlConfig(), + "google_identity_platform_oauth_idp_config": resourceIdentityPlatformOauthIdpConfig(), + "google_identity_platform_tenant_oauth_idp_config": resourceIdentityPlatformTenantOauthIdpConfig(), + "google_identity_platform_tenant": resourceIdentityPlatformTenant(), + "google_kms_key_ring": resourceKMSKeyRing(), + "google_kms_crypto_key": resourceKMSCryptoKey(), + "google_logging_metric": resourceLoggingMetric(), + "google_ml_engine_model": resourceMLEngineModel(), + "google_monitoring_alert_policy": resourceMonitoringAlertPolicy(), + "google_monitoring_group": resourceMonitoringGroup(), + "google_monitoring_notification_channel": resourceMonitoringNotificationChannel(), + "google_monitoring_uptime_check_config": resourceMonitoringUptimeCheckConfig(), + "google_pubsub_topic": resourcePubsubTopic(), + "google_pubsub_topic_iam_binding": ResourceIamBinding(PubsubTopicIamSchema, PubsubTopicIamUpdaterProducer, PubsubTopicIdParseFunc), + "google_pubsub_topic_iam_member": ResourceIamMember(PubsubTopicIamSchema, PubsubTopicIamUpdaterProducer, PubsubTopicIdParseFunc), + "google_pubsub_topic_iam_policy": ResourceIamPolicy(PubsubTopicIamSchema, PubsubTopicIamUpdaterProducer, PubsubTopicIdParseFunc), + "google_pubsub_subscription": resourcePubsubSubscription(), + "google_redis_instance": resourceRedisInstance(), + "google_resource_manager_lien": resourceResourceManagerLien(), + "google_runtimeconfig_config_iam_binding": ResourceIamBinding(RuntimeConfigConfigIamSchema, RuntimeConfigConfigIamUpdaterProducer, RuntimeConfigConfigIdParseFunc), + "google_runtimeconfig_config_iam_member": ResourceIamMember(RuntimeConfigConfigIamSchema, RuntimeConfigConfigIamUpdaterProducer, RuntimeConfigConfigIdParseFunc), + "google_runtimeconfig_config_iam_policy": ResourceIamPolicy(RuntimeConfigConfigIamSchema, RuntimeConfigConfigIamUpdaterProducer, RuntimeConfigConfigIdParseFunc), + "google_scc_source": resourceSecurityCenterSource(), + "google_sourcerepo_repository": resourceSourceRepoRepository(), + "google_sourcerepo_repository_iam_binding": ResourceIamBinding(SourceRepoRepositoryIamSchema, SourceRepoRepositoryIamUpdaterProducer, SourceRepoRepositoryIdParseFunc), + "google_sourcerepo_repository_iam_member": ResourceIamMember(SourceRepoRepositoryIamSchema, SourceRepoRepositoryIamUpdaterProducer, SourceRepoRepositoryIdParseFunc), + "google_sourcerepo_repository_iam_policy": ResourceIamPolicy(SourceRepoRepositoryIamSchema, SourceRepoRepositoryIamUpdaterProducer, SourceRepoRepositoryIdParseFunc), + "google_spanner_instance": resourceSpannerInstance(), + "google_spanner_database": resourceSpannerDatabase(), + "google_sql_database": resourceSQLDatabase(), + "google_storage_bucket_iam_binding": ResourceIamBinding(StorageBucketIamSchema, StorageBucketIamUpdaterProducer, StorageBucketIdParseFunc), + "google_storage_bucket_iam_member": ResourceIamMember(StorageBucketIamSchema, StorageBucketIamUpdaterProducer, StorageBucketIdParseFunc), + "google_storage_bucket_iam_policy": ResourceIamPolicy(StorageBucketIamSchema, StorageBucketIamUpdaterProducer, StorageBucketIdParseFunc), + "google_storage_bucket_access_control": resourceStorageBucketAccessControl(), + "google_storage_object_access_control": resourceStorageObjectAccessControl(), + "google_storage_default_object_access_control": resourceStorageDefaultObjectAccessControl(), + "google_tpu_node": resourceTPUNode(), }, map[string]*schema.Resource{ "google_app_engine_application": resourceAppEngineApplication(), @@ -778,6 +793,7 @@ func providerConfigure(d *schema.ResourceData, terraformVersion string) (interfa config.FilestoreBasePath = d.Get("filestore_custom_endpoint").(string) config.FirestoreBasePath = d.Get("firestore_custom_endpoint").(string) config.IapBasePath = d.Get("iap_custom_endpoint").(string) + config.IdentityPlatformBasePath = d.Get("identity_platform_custom_endpoint").(string) config.KMSBasePath = d.Get("kms_custom_endpoint").(string) config.LoggingBasePath = d.Get("logging_custom_endpoint").(string) config.MLEngineBasePath = d.Get("ml_engine_custom_endpoint").(string) diff --git a/google/resource_identity_platform_default_supported_idp_config.go b/google/resource_identity_platform_default_supported_idp_config.go new file mode 100644 index 00000000000..aa1d40d6f6b --- /dev/null +++ b/google/resource_identity_platform_default_supported_idp_config.go @@ -0,0 +1,286 @@ +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file in +// .github/CONTRIBUTING.md. +// +// ---------------------------------------------------------------------------- + +package google + +import ( + "fmt" + "log" + "reflect" + "strings" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" +) + +func resourceIdentityPlatformDefaultSupportedIdpConfig() *schema.Resource { + return &schema.Resource{ + Create: resourceIdentityPlatformDefaultSupportedIdpConfigCreate, + Read: resourceIdentityPlatformDefaultSupportedIdpConfigRead, + Update: resourceIdentityPlatformDefaultSupportedIdpConfigUpdate, + Delete: resourceIdentityPlatformDefaultSupportedIdpConfigDelete, + + Importer: &schema.ResourceImporter{ + State: resourceIdentityPlatformDefaultSupportedIdpConfigImport, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(4 * time.Minute), + Update: schema.DefaultTimeout(4 * time.Minute), + Delete: schema.DefaultTimeout(4 * time.Minute), + }, + + Schema: map[string]*schema.Schema{ + "client_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `OAuth client ID`, + }, + "client_secret": { + Type: schema.TypeString, + Required: true, + Description: `OAuth client secret`, + }, + "enabled": { + Type: schema.TypeBool, + Optional: true, + Description: `If this IDP allows the user to sign in`, + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: `The name of the DefaultSupportedIdpConfig resource`, + }, + "project": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + }, + }, + } +} + +func resourceIdentityPlatformDefaultSupportedIdpConfigCreate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + obj := make(map[string]interface{}) + clientIdProp, err := expandIdentityPlatformDefaultSupportedIdpConfigClientId(d.Get("client_id"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("client_id"); !isEmptyValue(reflect.ValueOf(clientIdProp)) && (ok || !reflect.DeepEqual(v, clientIdProp)) { + obj["clientId"] = clientIdProp + } + clientSecretProp, err := expandIdentityPlatformDefaultSupportedIdpConfigClientSecret(d.Get("client_secret"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("client_secret"); !isEmptyValue(reflect.ValueOf(clientSecretProp)) && (ok || !reflect.DeepEqual(v, clientSecretProp)) { + obj["clientSecret"] = clientSecretProp + } + enabledProp, err := expandIdentityPlatformDefaultSupportedIdpConfigEnabled(d.Get("enabled"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("enabled"); !isEmptyValue(reflect.ValueOf(enabledProp)) && (ok || !reflect.DeepEqual(v, enabledProp)) { + obj["enabled"] = enabledProp + } + + url, err := replaceVars(d, config, "{{IdentityPlatformBasePath}}projects/{{project}}/defaultSupportedIdpConfigs?idpId={{client_id}}") + if err != nil { + return err + } + + log.Printf("[DEBUG] Creating new DefaultSupportedIdpConfig: %#v", obj) + project, err := getProject(d, config) + if err != nil { + return err + } + res, err := sendRequestWithTimeout(config, "POST", project, url, obj, d.Timeout(schema.TimeoutCreate)) + if err != nil { + return fmt.Errorf("Error creating DefaultSupportedIdpConfig: %s", err) + } + + // Store the ID now + id, err := replaceVars(d, config, "projects/{{project}}/defaultSupportedIdpConfigs/{{client_id}}") + if err != nil { + return fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + log.Printf("[DEBUG] Finished creating DefaultSupportedIdpConfig %q: %#v", d.Id(), res) + + return resourceIdentityPlatformDefaultSupportedIdpConfigRead(d, meta) +} + +func resourceIdentityPlatformDefaultSupportedIdpConfigRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + url, err := replaceVars(d, config, "{{IdentityPlatformBasePath}}projects/{{project}}/defaultSupportedIdpConfigs/{{client_id}}") + if err != nil { + return err + } + + project, err := getProject(d, config) + if err != nil { + return err + } + res, err := sendRequest(config, "GET", project, url, nil) + if err != nil { + return handleNotFoundError(err, d, fmt.Sprintf("IdentityPlatformDefaultSupportedIdpConfig %q", d.Id())) + } + + if err := d.Set("project", project); err != nil { + return fmt.Errorf("Error reading DefaultSupportedIdpConfig: %s", err) + } + + if err := d.Set("name", flattenIdentityPlatformDefaultSupportedIdpConfigName(res["name"], d)); err != nil { + return fmt.Errorf("Error reading DefaultSupportedIdpConfig: %s", err) + } + if err := d.Set("client_id", flattenIdentityPlatformDefaultSupportedIdpConfigClientId(res["clientId"], d)); err != nil { + return fmt.Errorf("Error reading DefaultSupportedIdpConfig: %s", err) + } + if err := d.Set("client_secret", flattenIdentityPlatformDefaultSupportedIdpConfigClientSecret(res["clientSecret"], d)); err != nil { + return fmt.Errorf("Error reading DefaultSupportedIdpConfig: %s", err) + } + if err := d.Set("enabled", flattenIdentityPlatformDefaultSupportedIdpConfigEnabled(res["enabled"], d)); err != nil { + return fmt.Errorf("Error reading DefaultSupportedIdpConfig: %s", err) + } + + return nil +} + +func resourceIdentityPlatformDefaultSupportedIdpConfigUpdate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + project, err := getProject(d, config) + if err != nil { + return err + } + + obj := make(map[string]interface{}) + clientSecretProp, err := expandIdentityPlatformDefaultSupportedIdpConfigClientSecret(d.Get("client_secret"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("client_secret"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, clientSecretProp)) { + obj["clientSecret"] = clientSecretProp + } + enabledProp, err := expandIdentityPlatformDefaultSupportedIdpConfigEnabled(d.Get("enabled"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("enabled"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, enabledProp)) { + obj["enabled"] = enabledProp + } + + url, err := replaceVars(d, config, "{{IdentityPlatformBasePath}}projects/{{project}}/defaultSupportedIdpConfigs/{{client_id}}") + if err != nil { + return err + } + + log.Printf("[DEBUG] Updating DefaultSupportedIdpConfig %q: %#v", d.Id(), obj) + updateMask := []string{} + + if d.HasChange("client_secret") { + updateMask = append(updateMask, "clientSecret") + } + + if d.HasChange("enabled") { + updateMask = append(updateMask, "enabled") + } + // updateMask is a URL parameter but not present in the schema, so replaceVars + // won't set it + url, err = addQueryParams(url, map[string]string{"updateMask": strings.Join(updateMask, ",")}) + if err != nil { + return err + } + _, err = sendRequestWithTimeout(config, "PATCH", project, url, obj, d.Timeout(schema.TimeoutUpdate)) + + if err != nil { + return fmt.Errorf("Error updating DefaultSupportedIdpConfig %q: %s", d.Id(), err) + } + + return resourceIdentityPlatformDefaultSupportedIdpConfigRead(d, meta) +} + +func resourceIdentityPlatformDefaultSupportedIdpConfigDelete(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + project, err := getProject(d, config) + if err != nil { + return err + } + + url, err := replaceVars(d, config, "{{IdentityPlatformBasePath}}projects/{{project}}/defaultSupportedIdpConfigs/{{client_id}}") + if err != nil { + return err + } + + var obj map[string]interface{} + log.Printf("[DEBUG] Deleting DefaultSupportedIdpConfig %q", d.Id()) + + res, err := sendRequestWithTimeout(config, "DELETE", project, url, obj, d.Timeout(schema.TimeoutDelete)) + if err != nil { + return handleNotFoundError(err, d, "DefaultSupportedIdpConfig") + } + + log.Printf("[DEBUG] Finished deleting DefaultSupportedIdpConfig %q: %#v", d.Id(), res) + return nil +} + +func resourceIdentityPlatformDefaultSupportedIdpConfigImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + config := meta.(*Config) + if err := parseImportId([]string{ + "projects/(?P[^/]+)/defaultSupportedIdpConfigs/(?P[^/]+)", + "(?P[^/]+)/(?P[^/]+)", + "(?P[^/]+)", + }, d, config); err != nil { + return nil, err + } + + // Replace import id for the resource id + id, err := replaceVars(d, config, "projects/{{project}}/defaultSupportedIdpConfigs/{{client_id}}") + if err != nil { + return nil, fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + return []*schema.ResourceData{d}, nil +} + +func flattenIdentityPlatformDefaultSupportedIdpConfigName(v interface{}, d *schema.ResourceData) interface{} { + return v +} + +func flattenIdentityPlatformDefaultSupportedIdpConfigClientId(v interface{}, d *schema.ResourceData) interface{} { + return v +} + +func flattenIdentityPlatformDefaultSupportedIdpConfigClientSecret(v interface{}, d *schema.ResourceData) interface{} { + return v +} + +func flattenIdentityPlatformDefaultSupportedIdpConfigEnabled(v interface{}, d *schema.ResourceData) interface{} { + return v +} + +func expandIdentityPlatformDefaultSupportedIdpConfigClientId(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandIdentityPlatformDefaultSupportedIdpConfigClientSecret(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandIdentityPlatformDefaultSupportedIdpConfigEnabled(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} diff --git a/google/resource_identity_platform_default_supported_idp_config_test.go b/google/resource_identity_platform_default_supported_idp_config_test.go new file mode 100644 index 00000000000..de7da44b950 --- /dev/null +++ b/google/resource_identity_platform_default_supported_idp_config_test.go @@ -0,0 +1,88 @@ +package google + +import ( + "fmt" + "strings" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/terraform" +) + +func TestAccIdentityPlatformDefaultSupportedIdpConfig_defaultSupportedIdpConfigUpdate(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(10), + } + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckIdentityPlatformDefaultSupportedIdpConfigDestroy, + Steps: []resource.TestStep{ + { + Config: testAccIdentityPlatformDefaultSupportedIdpConfig_defaultSupportedIdpConfigBasic(context), + }, + { + ResourceName: "google_identity_platform_default_supported_idp_config.idp_config", + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccIdentityPlatformDefaultSupportedIdpConfig_defaultSupportedIdpConfigUpdate(context), + }, + { + ResourceName: "google_identity_platform_default_supported_idp_config.idp_config", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccCheckIdentityPlatformDefaultSupportedIdpConfigDestroy(s *terraform.State) error { + for name, rs := range s.RootModule().Resources { + if rs.Type != "google_identity_platform_default_supported_idp_config" { + continue + } + if strings.HasPrefix(name, "data.") { + continue + } + + config := testAccProvider.Meta().(*Config) + + url, err := replaceVarsForTest(config, rs, "{{IdentityPlatformBasePath}}projects/{{project}}/defaultSupportedIdpConfigs/{{client_id}}") + if err != nil { + return err + } + + _, err = sendRequest(config, "GET", "", url, nil) + if err == nil { + return fmt.Errorf("IdentityPlatformDefaultSupportedIdpConfig still exists at %s", url) + } + } + + return nil +} + +func testAccIdentityPlatformDefaultSupportedIdpConfig_defaultSupportedIdpConfigBasic(context map[string]interface{}) string { + return Nprintf(` +resource "google_identity_platform_default_supported_idp_config" "idp_config" { + enabled = true + client_id = "playgames.google.com" + client_secret = "secret" +} +`, context) +} + +func testAccIdentityPlatformDefaultSupportedIdpConfig_defaultSupportedIdpConfigUpdate(context map[string]interface{}) string { + return Nprintf(` +resource "google_identity_platform_default_supported_idp_config" "idp_config" { + enabled = false + client_id = "playgames.google.com" + client_secret = "anothersecret" +} +`, context) +} diff --git a/google/resource_identity_platform_inbound_saml_config.go b/google/resource_identity_platform_inbound_saml_config.go new file mode 100644 index 00000000000..fd9dd03c2cd --- /dev/null +++ b/google/resource_identity_platform_inbound_saml_config.go @@ -0,0 +1,636 @@ +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file in +// .github/CONTRIBUTING.md. +// +// ---------------------------------------------------------------------------- + +package google + +import ( + "fmt" + "log" + "reflect" + "strings" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" +) + +func resourceIdentityPlatformInboundSamlConfig() *schema.Resource { + return &schema.Resource{ + Create: resourceIdentityPlatformInboundSamlConfigCreate, + Read: resourceIdentityPlatformInboundSamlConfigRead, + Update: resourceIdentityPlatformInboundSamlConfigUpdate, + Delete: resourceIdentityPlatformInboundSamlConfigDelete, + + Importer: &schema.ResourceImporter{ + State: resourceIdentityPlatformInboundSamlConfigImport, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(4 * time.Minute), + Update: schema.DefaultTimeout(4 * time.Minute), + Delete: schema.DefaultTimeout(4 * time.Minute), + }, + + Schema: map[string]*schema.Schema{ + "display_name": { + Type: schema.TypeString, + Required: true, + Description: `Human friendly display name.`, + }, + "idp_config": { + Type: schema.TypeList, + Required: true, + Description: `SAML IdP configuration when the project acts as the relying party`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "idp_certificates": { + Type: schema.TypeList, + Required: true, + Description: `The IdP's certificate data to verify the signature in the SAMLResponse issued by the IDP.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "x509_certificate": { + Type: schema.TypeString, + Optional: true, + Description: `The IdP's x509 certificate.`, + }, + }, + }, + }, + "idp_entity_id": { + Type: schema.TypeString, + Required: true, + Description: `Unique identifier for all SAML entities`, + }, + "sso_url": { + Type: schema.TypeString, + Required: true, + Description: `URL to send Authentication request to.`, + }, + "sign_request": { + Type: schema.TypeBool, + Optional: true, + Description: `Indicates if outbounding SAMLRequest should be signed.`, + }, + }, + }, + }, + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `The name of the InboundSamlConfig resource. Must start with 'saml.' and can only have alphanumeric characters, +hyphens, underscores or periods. The part after 'saml.' must also start with a lowercase letter, end with an +alphanumeric character, and have at least 2 characters.`, + }, + "sp_config": { + Type: schema.TypeList, + Required: true, + Description: `SAML SP (Service Provider) configuration when the project acts as the relying party to receive +and accept an authentication assertion issued by a SAML identity provider.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "callback_uri": { + Type: schema.TypeString, + Optional: true, + Description: `Callback URI where responses from IDP are handled. Must start with 'https://'.`, + }, + "sp_entity_id": { + Type: schema.TypeString, + Optional: true, + Description: `Unique identifier for all SAML entities.`, + }, + "sp_certificates": { + Type: schema.TypeList, + Computed: true, + Description: `The IDP's certificate data to verify the signature in the SAMLResponse issued by the IDP.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "x509_certificate": { + Type: schema.TypeString, + Computed: true, + Description: `The x509 certificate`, + }, + }, + }, + }, + }, + }, + }, + "enabled": { + Type: schema.TypeBool, + Optional: true, + Description: `If this config allows users to sign in with the provider.`, + }, + "project": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + }, + }, + } +} + +func resourceIdentityPlatformInboundSamlConfigCreate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + obj := make(map[string]interface{}) + nameProp, err := expandIdentityPlatformInboundSamlConfigName(d.Get("name"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("name"); !isEmptyValue(reflect.ValueOf(nameProp)) && (ok || !reflect.DeepEqual(v, nameProp)) { + obj["name"] = nameProp + } + displayNameProp, err := expandIdentityPlatformInboundSamlConfigDisplayName(d.Get("display_name"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("display_name"); !isEmptyValue(reflect.ValueOf(displayNameProp)) && (ok || !reflect.DeepEqual(v, displayNameProp)) { + obj["displayName"] = displayNameProp + } + enabledProp, err := expandIdentityPlatformInboundSamlConfigEnabled(d.Get("enabled"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("enabled"); !isEmptyValue(reflect.ValueOf(enabledProp)) && (ok || !reflect.DeepEqual(v, enabledProp)) { + obj["enabled"] = enabledProp + } + idpConfigProp, err := expandIdentityPlatformInboundSamlConfigIdpConfig(d.Get("idp_config"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("idp_config"); !isEmptyValue(reflect.ValueOf(idpConfigProp)) && (ok || !reflect.DeepEqual(v, idpConfigProp)) { + obj["idpConfig"] = idpConfigProp + } + spConfigProp, err := expandIdentityPlatformInboundSamlConfigSpConfig(d.Get("sp_config"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("sp_config"); !isEmptyValue(reflect.ValueOf(spConfigProp)) && (ok || !reflect.DeepEqual(v, spConfigProp)) { + obj["spConfig"] = spConfigProp + } + + url, err := replaceVars(d, config, "{{IdentityPlatformBasePath}}projects/{{project}}/inboundSamlConfigs?inboundSamlConfigId={{name}}") + if err != nil { + return err + } + + log.Printf("[DEBUG] Creating new InboundSamlConfig: %#v", obj) + project, err := getProject(d, config) + if err != nil { + return err + } + res, err := sendRequestWithTimeout(config, "POST", project, url, obj, d.Timeout(schema.TimeoutCreate)) + if err != nil { + return fmt.Errorf("Error creating InboundSamlConfig: %s", err) + } + + // Store the ID now + id, err := replaceVars(d, config, "projects/{{project}}/inboundSamlConfigs/{{name}}") + if err != nil { + return fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + log.Printf("[DEBUG] Finished creating InboundSamlConfig %q: %#v", d.Id(), res) + + return resourceIdentityPlatformInboundSamlConfigRead(d, meta) +} + +func resourceIdentityPlatformInboundSamlConfigRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + url, err := replaceVars(d, config, "{{IdentityPlatformBasePath}}projects/{{project}}/inboundSamlConfigs/{{name}}") + if err != nil { + return err + } + + project, err := getProject(d, config) + if err != nil { + return err + } + res, err := sendRequest(config, "GET", project, url, nil) + if err != nil { + return handleNotFoundError(err, d, fmt.Sprintf("IdentityPlatformInboundSamlConfig %q", d.Id())) + } + + if err := d.Set("project", project); err != nil { + return fmt.Errorf("Error reading InboundSamlConfig: %s", err) + } + + if err := d.Set("name", flattenIdentityPlatformInboundSamlConfigName(res["name"], d)); err != nil { + return fmt.Errorf("Error reading InboundSamlConfig: %s", err) + } + if err := d.Set("display_name", flattenIdentityPlatformInboundSamlConfigDisplayName(res["displayName"], d)); err != nil { + return fmt.Errorf("Error reading InboundSamlConfig: %s", err) + } + if err := d.Set("enabled", flattenIdentityPlatformInboundSamlConfigEnabled(res["enabled"], d)); err != nil { + return fmt.Errorf("Error reading InboundSamlConfig: %s", err) + } + if err := d.Set("idp_config", flattenIdentityPlatformInboundSamlConfigIdpConfig(res["idpConfig"], d)); err != nil { + return fmt.Errorf("Error reading InboundSamlConfig: %s", err) + } + if err := d.Set("sp_config", flattenIdentityPlatformInboundSamlConfigSpConfig(res["spConfig"], d)); err != nil { + return fmt.Errorf("Error reading InboundSamlConfig: %s", err) + } + + return nil +} + +func resourceIdentityPlatformInboundSamlConfigUpdate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + project, err := getProject(d, config) + if err != nil { + return err + } + + obj := make(map[string]interface{}) + displayNameProp, err := expandIdentityPlatformInboundSamlConfigDisplayName(d.Get("display_name"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("display_name"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, displayNameProp)) { + obj["displayName"] = displayNameProp + } + enabledProp, err := expandIdentityPlatformInboundSamlConfigEnabled(d.Get("enabled"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("enabled"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, enabledProp)) { + obj["enabled"] = enabledProp + } + idpConfigProp, err := expandIdentityPlatformInboundSamlConfigIdpConfig(d.Get("idp_config"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("idp_config"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, idpConfigProp)) { + obj["idpConfig"] = idpConfigProp + } + spConfigProp, err := expandIdentityPlatformInboundSamlConfigSpConfig(d.Get("sp_config"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("sp_config"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, spConfigProp)) { + obj["spConfig"] = spConfigProp + } + + url, err := replaceVars(d, config, "{{IdentityPlatformBasePath}}projects/{{project}}/inboundSamlConfigs/{{name}}") + if err != nil { + return err + } + + log.Printf("[DEBUG] Updating InboundSamlConfig %q: %#v", d.Id(), obj) + updateMask := []string{} + + if d.HasChange("display_name") { + updateMask = append(updateMask, "displayName") + } + + if d.HasChange("enabled") { + updateMask = append(updateMask, "enabled") + } + + if d.HasChange("idp_config") { + updateMask = append(updateMask, "idpConfig") + } + + if d.HasChange("sp_config") { + updateMask = append(updateMask, "spConfig") + } + // updateMask is a URL parameter but not present in the schema, so replaceVars + // won't set it + url, err = addQueryParams(url, map[string]string{"updateMask": strings.Join(updateMask, ",")}) + if err != nil { + return err + } + _, err = sendRequestWithTimeout(config, "PATCH", project, url, obj, d.Timeout(schema.TimeoutUpdate)) + + if err != nil { + return fmt.Errorf("Error updating InboundSamlConfig %q: %s", d.Id(), err) + } + + return resourceIdentityPlatformInboundSamlConfigRead(d, meta) +} + +func resourceIdentityPlatformInboundSamlConfigDelete(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + project, err := getProject(d, config) + if err != nil { + return err + } + + url, err := replaceVars(d, config, "{{IdentityPlatformBasePath}}projects/{{project}}/inboundSamlConfigs/{{name}}") + if err != nil { + return err + } + + var obj map[string]interface{} + log.Printf("[DEBUG] Deleting InboundSamlConfig %q", d.Id()) + + res, err := sendRequestWithTimeout(config, "DELETE", project, url, obj, d.Timeout(schema.TimeoutDelete)) + if err != nil { + return handleNotFoundError(err, d, "InboundSamlConfig") + } + + log.Printf("[DEBUG] Finished deleting InboundSamlConfig %q: %#v", d.Id(), res) + return nil +} + +func resourceIdentityPlatformInboundSamlConfigImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + config := meta.(*Config) + if err := parseImportId([]string{ + "projects/(?P[^/]+)/inboundSamlConfigs/(?P[^/]+)", + "(?P[^/]+)/(?P[^/]+)", + "(?P[^/]+)", + }, d, config); err != nil { + return nil, err + } + + // Replace import id for the resource id + id, err := replaceVars(d, config, "projects/{{project}}/inboundSamlConfigs/{{name}}") + if err != nil { + return nil, fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + return []*schema.ResourceData{d}, nil +} + +func flattenIdentityPlatformInboundSamlConfigName(v interface{}, d *schema.ResourceData) interface{} { + if v == nil { + return v + } + return NameFromSelfLinkStateFunc(v) +} + +func flattenIdentityPlatformInboundSamlConfigDisplayName(v interface{}, d *schema.ResourceData) interface{} { + return v +} + +func flattenIdentityPlatformInboundSamlConfigEnabled(v interface{}, d *schema.ResourceData) interface{} { + return v +} + +func flattenIdentityPlatformInboundSamlConfigIdpConfig(v interface{}, d *schema.ResourceData) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["idp_entity_id"] = + flattenIdentityPlatformInboundSamlConfigIdpConfigIdpEntityId(original["idpEntityId"], d) + transformed["sso_url"] = + flattenIdentityPlatformInboundSamlConfigIdpConfigSsoUrl(original["ssoUrl"], d) + transformed["sign_request"] = + flattenIdentityPlatformInboundSamlConfigIdpConfigSignRequest(original["signRequest"], d) + transformed["idp_certificates"] = + flattenIdentityPlatformInboundSamlConfigIdpConfigIdpCertificates(original["idpCertificates"], d) + return []interface{}{transformed} +} +func flattenIdentityPlatformInboundSamlConfigIdpConfigIdpEntityId(v interface{}, d *schema.ResourceData) interface{} { + return v +} + +func flattenIdentityPlatformInboundSamlConfigIdpConfigSsoUrl(v interface{}, d *schema.ResourceData) interface{} { + return v +} + +func flattenIdentityPlatformInboundSamlConfigIdpConfigSignRequest(v interface{}, d *schema.ResourceData) interface{} { + return v +} + +func flattenIdentityPlatformInboundSamlConfigIdpConfigIdpCertificates(v interface{}, d *schema.ResourceData) interface{} { + if v == nil { + return v + } + l := v.([]interface{}) + transformed := make([]interface{}, 0, len(l)) + for _, raw := range l { + original := raw.(map[string]interface{}) + if len(original) < 1 { + // Do not include empty json objects coming back from the api + continue + } + transformed = append(transformed, map[string]interface{}{ + "x509_certificate": flattenIdentityPlatformInboundSamlConfigIdpConfigIdpCertificatesX509Certificate(original["x509Certificate"], d), + }) + } + return transformed +} +func flattenIdentityPlatformInboundSamlConfigIdpConfigIdpCertificatesX509Certificate(v interface{}, d *schema.ResourceData) interface{} { + return v +} + +func flattenIdentityPlatformInboundSamlConfigSpConfig(v interface{}, d *schema.ResourceData) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["sp_entity_id"] = + flattenIdentityPlatformInboundSamlConfigSpConfigSpEntityId(original["spEntityId"], d) + transformed["callback_uri"] = + flattenIdentityPlatformInboundSamlConfigSpConfigCallbackUri(original["callbackUri"], d) + transformed["sp_certificates"] = + flattenIdentityPlatformInboundSamlConfigSpConfigSpCertificates(original["spCertificates"], d) + return []interface{}{transformed} +} +func flattenIdentityPlatformInboundSamlConfigSpConfigSpEntityId(v interface{}, d *schema.ResourceData) interface{} { + return v +} + +func flattenIdentityPlatformInboundSamlConfigSpConfigCallbackUri(v interface{}, d *schema.ResourceData) interface{} { + return v +} + +func flattenIdentityPlatformInboundSamlConfigSpConfigSpCertificates(v interface{}, d *schema.ResourceData) interface{} { + if v == nil { + return v + } + l := v.([]interface{}) + transformed := make([]interface{}, 0, len(l)) + for _, raw := range l { + original := raw.(map[string]interface{}) + if len(original) < 1 { + // Do not include empty json objects coming back from the api + continue + } + transformed = append(transformed, map[string]interface{}{ + "x509_certificate": flattenIdentityPlatformInboundSamlConfigSpConfigSpCertificatesX509Certificate(original["x509Certificate"], d), + }) + } + return transformed +} +func flattenIdentityPlatformInboundSamlConfigSpConfigSpCertificatesX509Certificate(v interface{}, d *schema.ResourceData) interface{} { + return v +} + +func expandIdentityPlatformInboundSamlConfigName(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandIdentityPlatformInboundSamlConfigDisplayName(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandIdentityPlatformInboundSamlConfigEnabled(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandIdentityPlatformInboundSamlConfigIdpConfig(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 || l[0] == nil { + return nil, nil + } + raw := l[0] + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedIdpEntityId, err := expandIdentityPlatformInboundSamlConfigIdpConfigIdpEntityId(original["idp_entity_id"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedIdpEntityId); val.IsValid() && !isEmptyValue(val) { + transformed["idpEntityId"] = transformedIdpEntityId + } + + transformedSsoUrl, err := expandIdentityPlatformInboundSamlConfigIdpConfigSsoUrl(original["sso_url"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedSsoUrl); val.IsValid() && !isEmptyValue(val) { + transformed["ssoUrl"] = transformedSsoUrl + } + + transformedSignRequest, err := expandIdentityPlatformInboundSamlConfigIdpConfigSignRequest(original["sign_request"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedSignRequest); val.IsValid() && !isEmptyValue(val) { + transformed["signRequest"] = transformedSignRequest + } + + transformedIdpCertificates, err := expandIdentityPlatformInboundSamlConfigIdpConfigIdpCertificates(original["idp_certificates"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedIdpCertificates); val.IsValid() && !isEmptyValue(val) { + transformed["idpCertificates"] = transformedIdpCertificates + } + + return transformed, nil +} + +func expandIdentityPlatformInboundSamlConfigIdpConfigIdpEntityId(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandIdentityPlatformInboundSamlConfigIdpConfigSsoUrl(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandIdentityPlatformInboundSamlConfigIdpConfigSignRequest(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandIdentityPlatformInboundSamlConfigIdpConfigIdpCertificates(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + l := v.([]interface{}) + req := make([]interface{}, 0, len(l)) + for _, raw := range l { + if raw == nil { + continue + } + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedX509Certificate, err := expandIdentityPlatformInboundSamlConfigIdpConfigIdpCertificatesX509Certificate(original["x509_certificate"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedX509Certificate); val.IsValid() && !isEmptyValue(val) { + transformed["x509Certificate"] = transformedX509Certificate + } + + req = append(req, transformed) + } + return req, nil +} + +func expandIdentityPlatformInboundSamlConfigIdpConfigIdpCertificatesX509Certificate(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandIdentityPlatformInboundSamlConfigSpConfig(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 || l[0] == nil { + return nil, nil + } + raw := l[0] + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedSpEntityId, err := expandIdentityPlatformInboundSamlConfigSpConfigSpEntityId(original["sp_entity_id"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedSpEntityId); val.IsValid() && !isEmptyValue(val) { + transformed["spEntityId"] = transformedSpEntityId + } + + transformedCallbackUri, err := expandIdentityPlatformInboundSamlConfigSpConfigCallbackUri(original["callback_uri"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedCallbackUri); val.IsValid() && !isEmptyValue(val) { + transformed["callbackUri"] = transformedCallbackUri + } + + transformedSpCertificates, err := expandIdentityPlatformInboundSamlConfigSpConfigSpCertificates(original["sp_certificates"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedSpCertificates); val.IsValid() && !isEmptyValue(val) { + transformed["spCertificates"] = transformedSpCertificates + } + + return transformed, nil +} + +func expandIdentityPlatformInboundSamlConfigSpConfigSpEntityId(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandIdentityPlatformInboundSamlConfigSpConfigCallbackUri(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandIdentityPlatformInboundSamlConfigSpConfigSpCertificates(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + l := v.([]interface{}) + req := make([]interface{}, 0, len(l)) + for _, raw := range l { + if raw == nil { + continue + } + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedX509Certificate, err := expandIdentityPlatformInboundSamlConfigSpConfigSpCertificatesX509Certificate(original["x509_certificate"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedX509Certificate); val.IsValid() && !isEmptyValue(val) { + transformed["x509Certificate"] = transformedX509Certificate + } + + req = append(req, transformed) + } + return req, nil +} + +func expandIdentityPlatformInboundSamlConfigSpConfigSpCertificatesX509Certificate(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} diff --git a/google/resource_identity_platform_inbound_saml_config_generated_test.go b/google/resource_identity_platform_inbound_saml_config_generated_test.go new file mode 100644 index 00000000000..5d0153ec2c8 --- /dev/null +++ b/google/resource_identity_platform_inbound_saml_config_generated_test.go @@ -0,0 +1,96 @@ +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file in +// .github/CONTRIBUTING.md. +// +// ---------------------------------------------------------------------------- + +package google + +import ( + "fmt" + "strings" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/terraform" +) + +func TestAccIdentityPlatformInboundSamlConfig_identityPlatformInboundSamlConfigBasicExample(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(10), + } + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckIdentityPlatformInboundSamlConfigDestroy, + Steps: []resource.TestStep{ + { + Config: testAccIdentityPlatformInboundSamlConfig_identityPlatformInboundSamlConfigBasicExample(context), + }, + { + ResourceName: "google_identity_platform_inbound_saml_config.saml_config", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccIdentityPlatformInboundSamlConfig_identityPlatformInboundSamlConfigBasicExample(context map[string]interface{}) string { + return Nprintf(` +resource "google_identity_platform_inbound_saml_config" "saml_config" { + name = "saml.tf-config%{random_suffix}" + display_name = "Display Name" + idp_config { + idp_entity_id = "tf-idp%{random_suffix}" + sign_request = true + sso_url = "example.com" + idp_certificates { + x509_certificate = file("test-fixtures/rsa_cert.pem") + } + } + + sp_config { + sp_entity_id = "tf-sp%{random_suffix}" + callback_uri = "https://example.com" + } +} +`, context) +} + +func testAccCheckIdentityPlatformInboundSamlConfigDestroy(s *terraform.State) error { + for name, rs := range s.RootModule().Resources { + if rs.Type != "google_identity_platform_inbound_saml_config" { + continue + } + if strings.HasPrefix(name, "data.") { + continue + } + + config := testAccProvider.Meta().(*Config) + + url, err := replaceVarsForTest(config, rs, "{{IdentityPlatformBasePath}}projects/{{project}}/inboundSamlConfigs/{{name}}") + if err != nil { + return err + } + + _, err = sendRequest(config, "GET", "", url, nil) + if err == nil { + return fmt.Errorf("IdentityPlatformInboundSamlConfig still exists at %s", url) + } + } + + return nil +} diff --git a/google/resource_identity_platform_inbound_saml_config_test.go b/google/resource_identity_platform_inbound_saml_config_test.go new file mode 100644 index 00000000000..2a06d57cb65 --- /dev/null +++ b/google/resource_identity_platform_inbound_saml_config_test.go @@ -0,0 +1,83 @@ +package google + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" +) + +func TestAccIdentityPlatformInboundSamlConfig_inboundSamlConfigUpdate(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(10), + } + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckIdentityPlatformInboundSamlConfigDestroy, + Steps: []resource.TestStep{ + { + Config: testAccIdentityPlatformInboundSamlConfig_inboundSamlConfigBasic(context), + }, + { + ResourceName: "google_identity_platform_inbound_saml_config.saml_config", + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccIdentityPlatformInboundSamlConfig_inboundSamlConfigUpdate(context), + }, + { + ResourceName: "google_identity_platform_inbound_saml_config.saml_config", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccIdentityPlatformInboundSamlConfig_inboundSamlConfigBasic(context map[string]interface{}) string { + return Nprintf(` +resource "google_identity_platform_inbound_saml_config" "saml_config" { + name = "saml.tf-config%{random_suffix}" + display_name = "Display Name" + idp_config { + idp_entity_id = "tf-idp%{random_suffix}" + sso_url = "example.com" + idp_certificates { + x509_certificate = file("test-fixtures/rsa_cert.pem") + } + } + + sp_config { + sp_entity_id = "tf-sp%{random_suffix}" + callback_uri = "https://example.com" + } +} +`, context) +} + +func testAccIdentityPlatformInboundSamlConfig_inboundSamlConfigUpdate(context map[string]interface{}) string { + return Nprintf(` +resource "google_identity_platform_inbound_saml_config" "saml_config" { + name = "saml.tf-config%{random_suffix}" + display_name = "Display Name2" + idp_config { + idp_entity_id = "tf-idp%{random_suffix}" + sso_url = "example123.com" + sign_request = true + idp_certificates { + x509_certificate = file("test-fixtures/rsa_cert.pem") + } + } + + sp_config { + sp_entity_id = "tf-sp%{random_suffix}" + callback_uri = "https://example123.com" + } +} +`, context) +} diff --git a/google/resource_identity_platform_oauth_idp_config.go b/google/resource_identity_platform_oauth_idp_config.go new file mode 100644 index 00000000000..60e5e095abd --- /dev/null +++ b/google/resource_identity_platform_oauth_idp_config.go @@ -0,0 +1,373 @@ +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file in +// .github/CONTRIBUTING.md. +// +// ---------------------------------------------------------------------------- + +package google + +import ( + "fmt" + "log" + "reflect" + "strings" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" +) + +func resourceIdentityPlatformOauthIdpConfig() *schema.Resource { + return &schema.Resource{ + Create: resourceIdentityPlatformOauthIdpConfigCreate, + Read: resourceIdentityPlatformOauthIdpConfigRead, + Update: resourceIdentityPlatformOauthIdpConfigUpdate, + Delete: resourceIdentityPlatformOauthIdpConfigDelete, + + Importer: &schema.ResourceImporter{ + State: resourceIdentityPlatformOauthIdpConfigImport, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(4 * time.Minute), + Update: schema.DefaultTimeout(4 * time.Minute), + Delete: schema.DefaultTimeout(4 * time.Minute), + }, + + Schema: map[string]*schema.Schema{ + "client_id": { + Type: schema.TypeString, + Required: true, + Description: `The client id of an OAuth client.`, + }, + "issuer": { + Type: schema.TypeString, + Required: true, + Description: `For OIDC Idps, the issuer identifier.`, + }, + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `The name of the OauthIdpConfig. Must start with 'oidc.'.`, + }, + "client_secret": { + Type: schema.TypeString, + Optional: true, + Description: `The client secret of the OAuth client, to enable OIDC code flow.`, + }, + "display_name": { + Type: schema.TypeString, + Optional: true, + Description: `Human friendly display name.`, + }, + "enabled": { + Type: schema.TypeBool, + Optional: true, + Description: `If this config allows users to sign in with the provider.`, + }, + "project": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + }, + }, + } +} + +func resourceIdentityPlatformOauthIdpConfigCreate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + obj := make(map[string]interface{}) + nameProp, err := expandIdentityPlatformOauthIdpConfigName(d.Get("name"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("name"); !isEmptyValue(reflect.ValueOf(nameProp)) && (ok || !reflect.DeepEqual(v, nameProp)) { + obj["name"] = nameProp + } + displayNameProp, err := expandIdentityPlatformOauthIdpConfigDisplayName(d.Get("display_name"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("display_name"); !isEmptyValue(reflect.ValueOf(displayNameProp)) && (ok || !reflect.DeepEqual(v, displayNameProp)) { + obj["displayName"] = displayNameProp + } + enabledProp, err := expandIdentityPlatformOauthIdpConfigEnabled(d.Get("enabled"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("enabled"); !isEmptyValue(reflect.ValueOf(enabledProp)) && (ok || !reflect.DeepEqual(v, enabledProp)) { + obj["enabled"] = enabledProp + } + issuerProp, err := expandIdentityPlatformOauthIdpConfigIssuer(d.Get("issuer"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("issuer"); !isEmptyValue(reflect.ValueOf(issuerProp)) && (ok || !reflect.DeepEqual(v, issuerProp)) { + obj["issuer"] = issuerProp + } + clientIdProp, err := expandIdentityPlatformOauthIdpConfigClientId(d.Get("client_id"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("client_id"); !isEmptyValue(reflect.ValueOf(clientIdProp)) && (ok || !reflect.DeepEqual(v, clientIdProp)) { + obj["clientId"] = clientIdProp + } + clientSecretProp, err := expandIdentityPlatformOauthIdpConfigClientSecret(d.Get("client_secret"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("client_secret"); !isEmptyValue(reflect.ValueOf(clientSecretProp)) && (ok || !reflect.DeepEqual(v, clientSecretProp)) { + obj["clientSecret"] = clientSecretProp + } + + url, err := replaceVars(d, config, "{{IdentityPlatformBasePath}}projects/{{project}}/oauthIdpConfigs?oauthIdpConfigId={{name}}") + if err != nil { + return err + } + + log.Printf("[DEBUG] Creating new OauthIdpConfig: %#v", obj) + project, err := getProject(d, config) + if err != nil { + return err + } + res, err := sendRequestWithTimeout(config, "POST", project, url, obj, d.Timeout(schema.TimeoutCreate)) + if err != nil { + return fmt.Errorf("Error creating OauthIdpConfig: %s", err) + } + + // Store the ID now + id, err := replaceVars(d, config, "projects/{{project}}/oauthIdpConfigs/{{name}}") + if err != nil { + return fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + log.Printf("[DEBUG] Finished creating OauthIdpConfig %q: %#v", d.Id(), res) + + return resourceIdentityPlatformOauthIdpConfigRead(d, meta) +} + +func resourceIdentityPlatformOauthIdpConfigRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + url, err := replaceVars(d, config, "{{IdentityPlatformBasePath}}projects/{{project}}/oauthIdpConfigs/{{name}}") + if err != nil { + return err + } + + project, err := getProject(d, config) + if err != nil { + return err + } + res, err := sendRequest(config, "GET", project, url, nil) + if err != nil { + return handleNotFoundError(err, d, fmt.Sprintf("IdentityPlatformOauthIdpConfig %q", d.Id())) + } + + if err := d.Set("project", project); err != nil { + return fmt.Errorf("Error reading OauthIdpConfig: %s", err) + } + + if err := d.Set("name", flattenIdentityPlatformOauthIdpConfigName(res["name"], d)); err != nil { + return fmt.Errorf("Error reading OauthIdpConfig: %s", err) + } + if err := d.Set("display_name", flattenIdentityPlatformOauthIdpConfigDisplayName(res["displayName"], d)); err != nil { + return fmt.Errorf("Error reading OauthIdpConfig: %s", err) + } + if err := d.Set("enabled", flattenIdentityPlatformOauthIdpConfigEnabled(res["enabled"], d)); err != nil { + return fmt.Errorf("Error reading OauthIdpConfig: %s", err) + } + if err := d.Set("issuer", flattenIdentityPlatformOauthIdpConfigIssuer(res["issuer"], d)); err != nil { + return fmt.Errorf("Error reading OauthIdpConfig: %s", err) + } + if err := d.Set("client_id", flattenIdentityPlatformOauthIdpConfigClientId(res["clientId"], d)); err != nil { + return fmt.Errorf("Error reading OauthIdpConfig: %s", err) + } + if err := d.Set("client_secret", flattenIdentityPlatformOauthIdpConfigClientSecret(res["clientSecret"], d)); err != nil { + return fmt.Errorf("Error reading OauthIdpConfig: %s", err) + } + + return nil +} + +func resourceIdentityPlatformOauthIdpConfigUpdate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + project, err := getProject(d, config) + if err != nil { + return err + } + + obj := make(map[string]interface{}) + displayNameProp, err := expandIdentityPlatformOauthIdpConfigDisplayName(d.Get("display_name"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("display_name"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, displayNameProp)) { + obj["displayName"] = displayNameProp + } + enabledProp, err := expandIdentityPlatformOauthIdpConfigEnabled(d.Get("enabled"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("enabled"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, enabledProp)) { + obj["enabled"] = enabledProp + } + issuerProp, err := expandIdentityPlatformOauthIdpConfigIssuer(d.Get("issuer"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("issuer"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, issuerProp)) { + obj["issuer"] = issuerProp + } + clientIdProp, err := expandIdentityPlatformOauthIdpConfigClientId(d.Get("client_id"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("client_id"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, clientIdProp)) { + obj["clientId"] = clientIdProp + } + clientSecretProp, err := expandIdentityPlatformOauthIdpConfigClientSecret(d.Get("client_secret"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("client_secret"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, clientSecretProp)) { + obj["clientSecret"] = clientSecretProp + } + + url, err := replaceVars(d, config, "{{IdentityPlatformBasePath}}projects/{{project}}/oauthIdpConfigs/{{name}}") + if err != nil { + return err + } + + log.Printf("[DEBUG] Updating OauthIdpConfig %q: %#v", d.Id(), obj) + updateMask := []string{} + + if d.HasChange("display_name") { + updateMask = append(updateMask, "displayName") + } + + if d.HasChange("enabled") { + updateMask = append(updateMask, "enabled") + } + + if d.HasChange("issuer") { + updateMask = append(updateMask, "issuer") + } + + if d.HasChange("client_id") { + updateMask = append(updateMask, "clientId") + } + + if d.HasChange("client_secret") { + updateMask = append(updateMask, "clientSecret") + } + // updateMask is a URL parameter but not present in the schema, so replaceVars + // won't set it + url, err = addQueryParams(url, map[string]string{"updateMask": strings.Join(updateMask, ",")}) + if err != nil { + return err + } + _, err = sendRequestWithTimeout(config, "PATCH", project, url, obj, d.Timeout(schema.TimeoutUpdate)) + + if err != nil { + return fmt.Errorf("Error updating OauthIdpConfig %q: %s", d.Id(), err) + } + + return resourceIdentityPlatformOauthIdpConfigRead(d, meta) +} + +func resourceIdentityPlatformOauthIdpConfigDelete(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + project, err := getProject(d, config) + if err != nil { + return err + } + + url, err := replaceVars(d, config, "{{IdentityPlatformBasePath}}projects/{{project}}/oauthIdpConfigs/{{name}}") + if err != nil { + return err + } + + var obj map[string]interface{} + log.Printf("[DEBUG] Deleting OauthIdpConfig %q", d.Id()) + + res, err := sendRequestWithTimeout(config, "DELETE", project, url, obj, d.Timeout(schema.TimeoutDelete)) + if err != nil { + return handleNotFoundError(err, d, "OauthIdpConfig") + } + + log.Printf("[DEBUG] Finished deleting OauthIdpConfig %q: %#v", d.Id(), res) + return nil +} + +func resourceIdentityPlatformOauthIdpConfigImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + config := meta.(*Config) + if err := parseImportId([]string{ + "projects/(?P[^/]+)/oauthIdpConfigs/(?P[^/]+)", + "(?P[^/]+)/(?P[^/]+)", + "(?P[^/]+)", + }, d, config); err != nil { + return nil, err + } + + // Replace import id for the resource id + id, err := replaceVars(d, config, "projects/{{project}}/oauthIdpConfigs/{{name}}") + if err != nil { + return nil, fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + return []*schema.ResourceData{d}, nil +} + +func flattenIdentityPlatformOauthIdpConfigName(v interface{}, d *schema.ResourceData) interface{} { + if v == nil { + return v + } + return NameFromSelfLinkStateFunc(v) +} + +func flattenIdentityPlatformOauthIdpConfigDisplayName(v interface{}, d *schema.ResourceData) interface{} { + return v +} + +func flattenIdentityPlatformOauthIdpConfigEnabled(v interface{}, d *schema.ResourceData) interface{} { + return v +} + +func flattenIdentityPlatformOauthIdpConfigIssuer(v interface{}, d *schema.ResourceData) interface{} { + return v +} + +func flattenIdentityPlatformOauthIdpConfigClientId(v interface{}, d *schema.ResourceData) interface{} { + return v +} + +func flattenIdentityPlatformOauthIdpConfigClientSecret(v interface{}, d *schema.ResourceData) interface{} { + return v +} + +func expandIdentityPlatformOauthIdpConfigName(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandIdentityPlatformOauthIdpConfigDisplayName(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandIdentityPlatformOauthIdpConfigEnabled(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandIdentityPlatformOauthIdpConfigIssuer(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandIdentityPlatformOauthIdpConfigClientId(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandIdentityPlatformOauthIdpConfigClientSecret(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} diff --git a/google/resource_identity_platform_oauth_idp_config_generated_test.go b/google/resource_identity_platform_oauth_idp_config_generated_test.go new file mode 100644 index 00000000000..50c9bfe5db3 --- /dev/null +++ b/google/resource_identity_platform_oauth_idp_config_generated_test.go @@ -0,0 +1,87 @@ +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file in +// .github/CONTRIBUTING.md. +// +// ---------------------------------------------------------------------------- + +package google + +import ( + "fmt" + "strings" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/terraform" +) + +func TestAccIdentityPlatformOauthIdpConfig_identityPlatformOauthIdpConfigBasicExample(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(10), + } + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckIdentityPlatformOauthIdpConfigDestroy, + Steps: []resource.TestStep{ + { + Config: testAccIdentityPlatformOauthIdpConfig_identityPlatformOauthIdpConfigBasicExample(context), + }, + { + ResourceName: "google_identity_platform_oauth_idp_config.oauth_idp_config", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccIdentityPlatformOauthIdpConfig_identityPlatformOauthIdpConfigBasicExample(context map[string]interface{}) string { + return Nprintf(` +resource "google_identity_platform_oauth_idp_config" "oauth_idp_config" { + name = "oidc.oauth-idp-config%{random_suffix}" + display_name = "Display Name" + client_id = "client-id" + issuer = "issuer" + enabled = true + client_secret = "secret" +} +`, context) +} + +func testAccCheckIdentityPlatformOauthIdpConfigDestroy(s *terraform.State) error { + for name, rs := range s.RootModule().Resources { + if rs.Type != "google_identity_platform_oauth_idp_config" { + continue + } + if strings.HasPrefix(name, "data.") { + continue + } + + config := testAccProvider.Meta().(*Config) + + url, err := replaceVarsForTest(config, rs, "{{IdentityPlatformBasePath}}projects/{{project}}/oauthIdpConfigs/{{name}}") + if err != nil { + return err + } + + _, err = sendRequest(config, "GET", "", url, nil) + if err == nil { + return fmt.Errorf("IdentityPlatformOauthIdpConfig still exists at %s", url) + } + } + + return nil +} diff --git a/google/resource_identity_platform_tenant.go b/google/resource_identity_platform_tenant.go new file mode 100644 index 00000000000..087f29eec91 --- /dev/null +++ b/google/resource_identity_platform_tenant.go @@ -0,0 +1,345 @@ +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file in +// .github/CONTRIBUTING.md. +// +// ---------------------------------------------------------------------------- + +package google + +import ( + "fmt" + "log" + "reflect" + "strings" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" +) + +func resourceIdentityPlatformTenant() *schema.Resource { + return &schema.Resource{ + Create: resourceIdentityPlatformTenantCreate, + Read: resourceIdentityPlatformTenantRead, + Update: resourceIdentityPlatformTenantUpdate, + Delete: resourceIdentityPlatformTenantDelete, + + Importer: &schema.ResourceImporter{ + State: resourceIdentityPlatformTenantImport, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(4 * time.Minute), + Update: schema.DefaultTimeout(4 * time.Minute), + Delete: schema.DefaultTimeout(4 * time.Minute), + }, + + Schema: map[string]*schema.Schema{ + "display_name": { + Type: schema.TypeString, + Required: true, + Description: `Human friendly display name of the tenant.`, + }, + "allow_password_signup": { + Type: schema.TypeBool, + Optional: true, + Description: `Whether to allow email/password user authentication.`, + }, + "disable_auth": { + Type: schema.TypeBool, + Optional: true, + Description: `Whether authentication is disabled for the tenant. If true, the users under +the disabled tenant are not allowed to sign-in. Admins of the disabled tenant +are not able to manage its users.`, + }, + "enable_email_link_signin": { + Type: schema.TypeBool, + Optional: true, + Description: `Whether to enable email link user authentication.`, + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: `The name of the tenant that is generated by the server`, + }, + "project": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + }, + }, + } +} + +func resourceIdentityPlatformTenantCreate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + obj := make(map[string]interface{}) + displayNameProp, err := expandIdentityPlatformTenantDisplayName(d.Get("display_name"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("display_name"); !isEmptyValue(reflect.ValueOf(displayNameProp)) && (ok || !reflect.DeepEqual(v, displayNameProp)) { + obj["displayName"] = displayNameProp + } + allowPasswordSignupProp, err := expandIdentityPlatformTenantAllowPasswordSignup(d.Get("allow_password_signup"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("allow_password_signup"); !isEmptyValue(reflect.ValueOf(allowPasswordSignupProp)) && (ok || !reflect.DeepEqual(v, allowPasswordSignupProp)) { + obj["allowPasswordSignup"] = allowPasswordSignupProp + } + enableEmailLinkSigninProp, err := expandIdentityPlatformTenantEnableEmailLinkSignin(d.Get("enable_email_link_signin"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("enable_email_link_signin"); !isEmptyValue(reflect.ValueOf(enableEmailLinkSigninProp)) && (ok || !reflect.DeepEqual(v, enableEmailLinkSigninProp)) { + obj["enableEmailLinkSignin"] = enableEmailLinkSigninProp + } + disableAuthProp, err := expandIdentityPlatformTenantDisableAuth(d.Get("disable_auth"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("disable_auth"); !isEmptyValue(reflect.ValueOf(disableAuthProp)) && (ok || !reflect.DeepEqual(v, disableAuthProp)) { + obj["disableAuth"] = disableAuthProp + } + + url, err := replaceVars(d, config, "{{IdentityPlatformBasePath}}projects/{{project}}/tenants") + if err != nil { + return err + } + + log.Printf("[DEBUG] Creating new Tenant: %#v", obj) + project, err := getProject(d, config) + if err != nil { + return err + } + res, err := sendRequestWithTimeout(config, "POST", project, url, obj, d.Timeout(schema.TimeoutCreate)) + if err != nil { + return fmt.Errorf("Error creating Tenant: %s", err) + } + + // Store the ID now + id, err := replaceVars(d, config, "projects/{{project}}/tenants/{{name}}") + if err != nil { + return fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + log.Printf("[DEBUG] Finished creating Tenant %q: %#v", d.Id(), res) + + // `name` is autogenerated from the api so needs to be set post-create + name, ok := res["name"] + if !ok { + return fmt.Errorf("Create response didn't contain critical fields. Create may not have succeeded.") + } + d.Set("name", GetResourceNameFromSelfLink(name.(string))) + // Store the ID now that we have set the computed name + id, err = replaceVars(d, config, "projects/{{project}}/tenants/{{name}}") + if err != nil { + return fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + return resourceIdentityPlatformTenantRead(d, meta) +} + +func resourceIdentityPlatformTenantRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + url, err := replaceVars(d, config, "{{IdentityPlatformBasePath}}projects/{{project}}/tenants/{{name}}") + if err != nil { + return err + } + + project, err := getProject(d, config) + if err != nil { + return err + } + res, err := sendRequest(config, "GET", project, url, nil) + if err != nil { + return handleNotFoundError(err, d, fmt.Sprintf("IdentityPlatformTenant %q", d.Id())) + } + + if err := d.Set("project", project); err != nil { + return fmt.Errorf("Error reading Tenant: %s", err) + } + + if err := d.Set("name", flattenIdentityPlatformTenantName(res["name"], d)); err != nil { + return fmt.Errorf("Error reading Tenant: %s", err) + } + if err := d.Set("display_name", flattenIdentityPlatformTenantDisplayName(res["displayName"], d)); err != nil { + return fmt.Errorf("Error reading Tenant: %s", err) + } + if err := d.Set("allow_password_signup", flattenIdentityPlatformTenantAllowPasswordSignup(res["allowPasswordSignup"], d)); err != nil { + return fmt.Errorf("Error reading Tenant: %s", err) + } + if err := d.Set("enable_email_link_signin", flattenIdentityPlatformTenantEnableEmailLinkSignin(res["enableEmailLinkSignin"], d)); err != nil { + return fmt.Errorf("Error reading Tenant: %s", err) + } + if err := d.Set("disable_auth", flattenIdentityPlatformTenantDisableAuth(res["disableAuth"], d)); err != nil { + return fmt.Errorf("Error reading Tenant: %s", err) + } + + return nil +} + +func resourceIdentityPlatformTenantUpdate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + project, err := getProject(d, config) + if err != nil { + return err + } + + obj := make(map[string]interface{}) + displayNameProp, err := expandIdentityPlatformTenantDisplayName(d.Get("display_name"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("display_name"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, displayNameProp)) { + obj["displayName"] = displayNameProp + } + allowPasswordSignupProp, err := expandIdentityPlatformTenantAllowPasswordSignup(d.Get("allow_password_signup"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("allow_password_signup"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, allowPasswordSignupProp)) { + obj["allowPasswordSignup"] = allowPasswordSignupProp + } + enableEmailLinkSigninProp, err := expandIdentityPlatformTenantEnableEmailLinkSignin(d.Get("enable_email_link_signin"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("enable_email_link_signin"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, enableEmailLinkSigninProp)) { + obj["enableEmailLinkSignin"] = enableEmailLinkSigninProp + } + disableAuthProp, err := expandIdentityPlatformTenantDisableAuth(d.Get("disable_auth"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("disable_auth"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, disableAuthProp)) { + obj["disableAuth"] = disableAuthProp + } + + url, err := replaceVars(d, config, "{{IdentityPlatformBasePath}}projects/{{project}}/tenants/{{name}}") + if err != nil { + return err + } + + log.Printf("[DEBUG] Updating Tenant %q: %#v", d.Id(), obj) + updateMask := []string{} + + if d.HasChange("display_name") { + updateMask = append(updateMask, "displayName") + } + + if d.HasChange("allow_password_signup") { + updateMask = append(updateMask, "allowPasswordSignup") + } + + if d.HasChange("enable_email_link_signin") { + updateMask = append(updateMask, "enableEmailLinkSignin") + } + + if d.HasChange("disable_auth") { + updateMask = append(updateMask, "disableAuth") + } + // updateMask is a URL parameter but not present in the schema, so replaceVars + // won't set it + url, err = addQueryParams(url, map[string]string{"updateMask": strings.Join(updateMask, ",")}) + if err != nil { + return err + } + _, err = sendRequestWithTimeout(config, "PATCH", project, url, obj, d.Timeout(schema.TimeoutUpdate)) + + if err != nil { + return fmt.Errorf("Error updating Tenant %q: %s", d.Id(), err) + } + + return resourceIdentityPlatformTenantRead(d, meta) +} + +func resourceIdentityPlatformTenantDelete(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + project, err := getProject(d, config) + if err != nil { + return err + } + + url, err := replaceVars(d, config, "{{IdentityPlatformBasePath}}projects/{{project}}/tenants/{{name}}") + if err != nil { + return err + } + + var obj map[string]interface{} + log.Printf("[DEBUG] Deleting Tenant %q", d.Id()) + + res, err := sendRequestWithTimeout(config, "DELETE", project, url, obj, d.Timeout(schema.TimeoutDelete)) + if err != nil { + return handleNotFoundError(err, d, "Tenant") + } + + log.Printf("[DEBUG] Finished deleting Tenant %q: %#v", d.Id(), res) + return nil +} + +func resourceIdentityPlatformTenantImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + config := meta.(*Config) + if err := parseImportId([]string{ + "projects/(?P[^/]+)/tenants/(?P[^/]+)", + "(?P[^/]+)/(?P[^/]+)", + "(?P[^/]+)", + }, d, config); err != nil { + return nil, err + } + + // Replace import id for the resource id + id, err := replaceVars(d, config, "projects/{{project}}/tenants/{{name}}") + if err != nil { + return nil, fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + return []*schema.ResourceData{d}, nil +} + +func flattenIdentityPlatformTenantName(v interface{}, d *schema.ResourceData) interface{} { + if v == nil { + return v + } + return NameFromSelfLinkStateFunc(v) +} + +func flattenIdentityPlatformTenantDisplayName(v interface{}, d *schema.ResourceData) interface{} { + return v +} + +func flattenIdentityPlatformTenantAllowPasswordSignup(v interface{}, d *schema.ResourceData) interface{} { + return v +} + +func flattenIdentityPlatformTenantEnableEmailLinkSignin(v interface{}, d *schema.ResourceData) interface{} { + return v +} + +func flattenIdentityPlatformTenantDisableAuth(v interface{}, d *schema.ResourceData) interface{} { + return v +} + +func expandIdentityPlatformTenantDisplayName(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandIdentityPlatformTenantAllowPasswordSignup(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandIdentityPlatformTenantEnableEmailLinkSignin(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandIdentityPlatformTenantDisableAuth(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} diff --git a/google/resource_identity_platform_tenant_default_supported_idp_config.go b/google/resource_identity_platform_tenant_default_supported_idp_config.go new file mode 100644 index 00000000000..8845ec8273f --- /dev/null +++ b/google/resource_identity_platform_tenant_default_supported_idp_config.go @@ -0,0 +1,292 @@ +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file in +// .github/CONTRIBUTING.md. +// +// ---------------------------------------------------------------------------- + +package google + +import ( + "fmt" + "log" + "reflect" + "strings" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" +) + +func resourceIdentityPlatformTenantDefaultSupportedIdpConfig() *schema.Resource { + return &schema.Resource{ + Create: resourceIdentityPlatformTenantDefaultSupportedIdpConfigCreate, + Read: resourceIdentityPlatformTenantDefaultSupportedIdpConfigRead, + Update: resourceIdentityPlatformTenantDefaultSupportedIdpConfigUpdate, + Delete: resourceIdentityPlatformTenantDefaultSupportedIdpConfigDelete, + + Importer: &schema.ResourceImporter{ + State: resourceIdentityPlatformTenantDefaultSupportedIdpConfigImport, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(4 * time.Minute), + Update: schema.DefaultTimeout(4 * time.Minute), + Delete: schema.DefaultTimeout(4 * time.Minute), + }, + + Schema: map[string]*schema.Schema{ + "client_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `OAuth client ID`, + }, + "client_secret": { + Type: schema.TypeString, + Required: true, + Description: `OAuth client secret`, + }, + "tenant": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `The name of the tenant where this DefaultSupportedIdpConfig resource exists`, + }, + "enabled": { + Type: schema.TypeBool, + Optional: true, + Description: `If this IDP allows the user to sign in`, + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: `The name of the default supported IDP config resource`, + }, + "project": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + }, + }, + } +} + +func resourceIdentityPlatformTenantDefaultSupportedIdpConfigCreate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + obj := make(map[string]interface{}) + clientIdProp, err := expandIdentityPlatformTenantDefaultSupportedIdpConfigClientId(d.Get("client_id"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("client_id"); !isEmptyValue(reflect.ValueOf(clientIdProp)) && (ok || !reflect.DeepEqual(v, clientIdProp)) { + obj["clientId"] = clientIdProp + } + clientSecretProp, err := expandIdentityPlatformTenantDefaultSupportedIdpConfigClientSecret(d.Get("client_secret"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("client_secret"); !isEmptyValue(reflect.ValueOf(clientSecretProp)) && (ok || !reflect.DeepEqual(v, clientSecretProp)) { + obj["clientSecret"] = clientSecretProp + } + enabledProp, err := expandIdentityPlatformTenantDefaultSupportedIdpConfigEnabled(d.Get("enabled"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("enabled"); !isEmptyValue(reflect.ValueOf(enabledProp)) && (ok || !reflect.DeepEqual(v, enabledProp)) { + obj["enabled"] = enabledProp + } + + url, err := replaceVars(d, config, "{{IdentityPlatformBasePath}}projects/{{project}}/tenants/{{tenant}}/defaultSupportedIdpConfigs?idpId={{client_id}}") + if err != nil { + return err + } + + log.Printf("[DEBUG] Creating new TenantDefaultSupportedIdpConfig: %#v", obj) + project, err := getProject(d, config) + if err != nil { + return err + } + res, err := sendRequestWithTimeout(config, "POST", project, url, obj, d.Timeout(schema.TimeoutCreate)) + if err != nil { + return fmt.Errorf("Error creating TenantDefaultSupportedIdpConfig: %s", err) + } + + // Store the ID now + id, err := replaceVars(d, config, "projects/{{project}}/tenants/{{tenant}}/defaultSupportedIdpConfigs/{{client_id}}") + if err != nil { + return fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + log.Printf("[DEBUG] Finished creating TenantDefaultSupportedIdpConfig %q: %#v", d.Id(), res) + + return resourceIdentityPlatformTenantDefaultSupportedIdpConfigRead(d, meta) +} + +func resourceIdentityPlatformTenantDefaultSupportedIdpConfigRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + url, err := replaceVars(d, config, "{{IdentityPlatformBasePath}}projects/{{project}}/tenants/{{tenant}}/defaultSupportedIdpConfigs/{{client_id}}") + if err != nil { + return err + } + + project, err := getProject(d, config) + if err != nil { + return err + } + res, err := sendRequest(config, "GET", project, url, nil) + if err != nil { + return handleNotFoundError(err, d, fmt.Sprintf("IdentityPlatformTenantDefaultSupportedIdpConfig %q", d.Id())) + } + + if err := d.Set("project", project); err != nil { + return fmt.Errorf("Error reading TenantDefaultSupportedIdpConfig: %s", err) + } + + if err := d.Set("name", flattenIdentityPlatformTenantDefaultSupportedIdpConfigName(res["name"], d)); err != nil { + return fmt.Errorf("Error reading TenantDefaultSupportedIdpConfig: %s", err) + } + if err := d.Set("client_id", flattenIdentityPlatformTenantDefaultSupportedIdpConfigClientId(res["clientId"], d)); err != nil { + return fmt.Errorf("Error reading TenantDefaultSupportedIdpConfig: %s", err) + } + if err := d.Set("client_secret", flattenIdentityPlatformTenantDefaultSupportedIdpConfigClientSecret(res["clientSecret"], d)); err != nil { + return fmt.Errorf("Error reading TenantDefaultSupportedIdpConfig: %s", err) + } + if err := d.Set("enabled", flattenIdentityPlatformTenantDefaultSupportedIdpConfigEnabled(res["enabled"], d)); err != nil { + return fmt.Errorf("Error reading TenantDefaultSupportedIdpConfig: %s", err) + } + + return nil +} + +func resourceIdentityPlatformTenantDefaultSupportedIdpConfigUpdate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + project, err := getProject(d, config) + if err != nil { + return err + } + + obj := make(map[string]interface{}) + clientSecretProp, err := expandIdentityPlatformTenantDefaultSupportedIdpConfigClientSecret(d.Get("client_secret"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("client_secret"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, clientSecretProp)) { + obj["clientSecret"] = clientSecretProp + } + enabledProp, err := expandIdentityPlatformTenantDefaultSupportedIdpConfigEnabled(d.Get("enabled"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("enabled"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, enabledProp)) { + obj["enabled"] = enabledProp + } + + url, err := replaceVars(d, config, "{{IdentityPlatformBasePath}}projects/{{project}}/tenants/{{tenant}}/defaultSupportedIdpConfigs/{{client_id}}") + if err != nil { + return err + } + + log.Printf("[DEBUG] Updating TenantDefaultSupportedIdpConfig %q: %#v", d.Id(), obj) + updateMask := []string{} + + if d.HasChange("client_secret") { + updateMask = append(updateMask, "clientSecret") + } + + if d.HasChange("enabled") { + updateMask = append(updateMask, "enabled") + } + // updateMask is a URL parameter but not present in the schema, so replaceVars + // won't set it + url, err = addQueryParams(url, map[string]string{"updateMask": strings.Join(updateMask, ",")}) + if err != nil { + return err + } + _, err = sendRequestWithTimeout(config, "PATCH", project, url, obj, d.Timeout(schema.TimeoutUpdate)) + + if err != nil { + return fmt.Errorf("Error updating TenantDefaultSupportedIdpConfig %q: %s", d.Id(), err) + } + + return resourceIdentityPlatformTenantDefaultSupportedIdpConfigRead(d, meta) +} + +func resourceIdentityPlatformTenantDefaultSupportedIdpConfigDelete(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + project, err := getProject(d, config) + if err != nil { + return err + } + + url, err := replaceVars(d, config, "{{IdentityPlatformBasePath}}projects/{{project}}/tenants/{{tenant}}/defaultSupportedIdpConfigs/{{client_id}}") + if err != nil { + return err + } + + var obj map[string]interface{} + log.Printf("[DEBUG] Deleting TenantDefaultSupportedIdpConfig %q", d.Id()) + + res, err := sendRequestWithTimeout(config, "DELETE", project, url, obj, d.Timeout(schema.TimeoutDelete)) + if err != nil { + return handleNotFoundError(err, d, "TenantDefaultSupportedIdpConfig") + } + + log.Printf("[DEBUG] Finished deleting TenantDefaultSupportedIdpConfig %q: %#v", d.Id(), res) + return nil +} + +func resourceIdentityPlatformTenantDefaultSupportedIdpConfigImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + config := meta.(*Config) + if err := parseImportId([]string{ + "projects/(?P[^/]+)/tenants/(?P[^/]+)/defaultSupportedIdpConfigs/(?P[^/]+)", + "(?P[^/]+)/(?P[^/]+)/(?P[^/]+)", + "(?P[^/]+)/(?P[^/]+)", + }, d, config); err != nil { + return nil, err + } + + // Replace import id for the resource id + id, err := replaceVars(d, config, "projects/{{project}}/tenants/{{tenant}}/defaultSupportedIdpConfigs/{{client_id}}") + if err != nil { + return nil, fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + return []*schema.ResourceData{d}, nil +} + +func flattenIdentityPlatformTenantDefaultSupportedIdpConfigName(v interface{}, d *schema.ResourceData) interface{} { + return v +} + +func flattenIdentityPlatformTenantDefaultSupportedIdpConfigClientId(v interface{}, d *schema.ResourceData) interface{} { + return v +} + +func flattenIdentityPlatformTenantDefaultSupportedIdpConfigClientSecret(v interface{}, d *schema.ResourceData) interface{} { + return v +} + +func flattenIdentityPlatformTenantDefaultSupportedIdpConfigEnabled(v interface{}, d *schema.ResourceData) interface{} { + return v +} + +func expandIdentityPlatformTenantDefaultSupportedIdpConfigClientId(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandIdentityPlatformTenantDefaultSupportedIdpConfigClientSecret(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandIdentityPlatformTenantDefaultSupportedIdpConfigEnabled(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} diff --git a/google/resource_identity_platform_tenant_default_supported_idp_config_generated_test.go b/google/resource_identity_platform_tenant_default_supported_idp_config_generated_test.go new file mode 100644 index 00000000000..dea00f6c28d --- /dev/null +++ b/google/resource_identity_platform_tenant_default_supported_idp_config_generated_test.go @@ -0,0 +1,90 @@ +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file in +// .github/CONTRIBUTING.md. +// +// ---------------------------------------------------------------------------- + +package google + +import ( + "fmt" + "strings" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/terraform" +) + +func TestAccIdentityPlatformTenantDefaultSupportedIdpConfig_identityPlatformTenantDefaultSupportedIdpConfigBasicExample(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(10), + } + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckIdentityPlatformTenantDefaultSupportedIdpConfigDestroy, + Steps: []resource.TestStep{ + { + Config: testAccIdentityPlatformTenantDefaultSupportedIdpConfig_identityPlatformTenantDefaultSupportedIdpConfigBasicExample(context), + }, + { + ResourceName: "google_identity_platform_tenant_default_supported_idp_config.idp_config", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"tenant"}, + }, + }, + }) +} + +func testAccIdentityPlatformTenantDefaultSupportedIdpConfig_identityPlatformTenantDefaultSupportedIdpConfigBasicExample(context map[string]interface{}) string { + return Nprintf(` +resource "google_identity_platform_tenant" "tenant" { + display_name = "tenant" +} + +resource "google_identity_platform_tenant_default_supported_idp_config" "idp_config" { + enabled = true + tenant = google_identity_platform_tenant.tenant.name + client_id = "playgames.google.com" + client_secret = "secret" +} +`, context) +} + +func testAccCheckIdentityPlatformTenantDefaultSupportedIdpConfigDestroy(s *terraform.State) error { + for name, rs := range s.RootModule().Resources { + if rs.Type != "google_identity_platform_tenant_default_supported_idp_config" { + continue + } + if strings.HasPrefix(name, "data.") { + continue + } + + config := testAccProvider.Meta().(*Config) + + url, err := replaceVarsForTest(config, rs, "{{IdentityPlatformBasePath}}projects/{{project}}/tenants/{{tenant}}/defaultSupportedIdpConfigs/{{client_id}}") + if err != nil { + return err + } + + _, err = sendRequest(config, "GET", "", url, nil) + if err == nil { + return fmt.Errorf("IdentityPlatformTenantDefaultSupportedIdpConfig still exists at %s", url) + } + } + + return nil +} diff --git a/google/resource_identity_platform_tenant_generated_test.go b/google/resource_identity_platform_tenant_generated_test.go new file mode 100644 index 00000000000..0472127b784 --- /dev/null +++ b/google/resource_identity_platform_tenant_generated_test.go @@ -0,0 +1,83 @@ +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file in +// .github/CONTRIBUTING.md. +// +// ---------------------------------------------------------------------------- + +package google + +import ( + "fmt" + "strings" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/terraform" +) + +func TestAccIdentityPlatformTenant_identityPlatformTenantBasicExample(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(10), + } + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckIdentityPlatformTenantDestroy, + Steps: []resource.TestStep{ + { + Config: testAccIdentityPlatformTenant_identityPlatformTenantBasicExample(context), + }, + { + ResourceName: "google_identity_platform_tenant.tenant", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccIdentityPlatformTenant_identityPlatformTenantBasicExample(context map[string]interface{}) string { + return Nprintf(` +resource "google_identity_platform_tenant" "tenant" { + display_name = "tenant" + allow_password_signup = true +} +`, context) +} + +func testAccCheckIdentityPlatformTenantDestroy(s *terraform.State) error { + for name, rs := range s.RootModule().Resources { + if rs.Type != "google_identity_platform_tenant" { + continue + } + if strings.HasPrefix(name, "data.") { + continue + } + + config := testAccProvider.Meta().(*Config) + + url, err := replaceVarsForTest(config, rs, "{{IdentityPlatformBasePath}}projects/{{project}}/tenants/{{name}}") + if err != nil { + return err + } + + _, err = sendRequest(config, "GET", "", url, nil) + if err == nil { + return fmt.Errorf("IdentityPlatformTenant still exists at %s", url) + } + } + + return nil +} diff --git a/google/resource_identity_platform_tenant_inbound_saml_config.go b/google/resource_identity_platform_tenant_inbound_saml_config.go new file mode 100644 index 00000000000..846fca37c33 --- /dev/null +++ b/google/resource_identity_platform_tenant_inbound_saml_config.go @@ -0,0 +1,642 @@ +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file in +// .github/CONTRIBUTING.md. +// +// ---------------------------------------------------------------------------- + +package google + +import ( + "fmt" + "log" + "reflect" + "strings" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" +) + +func resourceIdentityPlatformTenantInboundSamlConfig() *schema.Resource { + return &schema.Resource{ + Create: resourceIdentityPlatformTenantInboundSamlConfigCreate, + Read: resourceIdentityPlatformTenantInboundSamlConfigRead, + Update: resourceIdentityPlatformTenantInboundSamlConfigUpdate, + Delete: resourceIdentityPlatformTenantInboundSamlConfigDelete, + + Importer: &schema.ResourceImporter{ + State: resourceIdentityPlatformTenantInboundSamlConfigImport, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(4 * time.Minute), + Update: schema.DefaultTimeout(4 * time.Minute), + Delete: schema.DefaultTimeout(4 * time.Minute), + }, + + Schema: map[string]*schema.Schema{ + "display_name": { + Type: schema.TypeString, + Required: true, + Description: `Human friendly display name.`, + }, + "idp_config": { + Type: schema.TypeList, + Required: true, + Description: `SAML IdP configuration when the project acts as the relying party`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "idp_certificates": { + Type: schema.TypeList, + Required: true, + Description: `The IDP's certificate data to verify the signature in the SAMLResponse issued by the IDP.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "x509_certificate": { + Type: schema.TypeString, + Optional: true, + Description: `The x509 certificate`, + }, + }, + }, + }, + "idp_entity_id": { + Type: schema.TypeString, + Required: true, + Description: `Unique identifier for all SAML entities`, + }, + "sso_url": { + Type: schema.TypeString, + Required: true, + Description: `URL to send Authentication request to.`, + }, + "sign_request": { + Type: schema.TypeBool, + Optional: true, + Description: `Indicates if outbounding SAMLRequest should be signed.`, + }, + }, + }, + }, + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `The name of the InboundSamlConfig resource. Must start with 'saml.' and can only have alphanumeric characters, +hyphens, underscores or periods. The part after 'saml.' must also start with a lowercase letter, end with an +alphanumeric character, and have at least 2 characters.`, + }, + "sp_config": { + Type: schema.TypeList, + Required: true, + Description: `SAML SP (Service Provider) configuration when the project acts as the relying party to receive +and accept an authentication assertion issued by a SAML identity provider.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "callback_uri": { + Type: schema.TypeString, + Required: true, + Description: `Callback URI where responses from IDP are handled. Must start with 'https://'.`, + }, + "sp_entity_id": { + Type: schema.TypeString, + Required: true, + Description: `Unique identifier for all SAML entities.`, + }, + "sp_certificates": { + Type: schema.TypeList, + Computed: true, + Description: `The IDP's certificate data to verify the signature in the SAMLResponse issued by the IDP.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "x509_certificate": { + Type: schema.TypeString, + Computed: true, + Description: `The x509 certificate`, + }, + }, + }, + }, + }, + }, + }, + "tenant": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `The name of the tenant where this inbound SAML config resource exists`, + }, + "enabled": { + Type: schema.TypeBool, + Optional: true, + Description: `If this config allows users to sign in with the provider.`, + }, + "project": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + }, + }, + } +} + +func resourceIdentityPlatformTenantInboundSamlConfigCreate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + obj := make(map[string]interface{}) + nameProp, err := expandIdentityPlatformTenantInboundSamlConfigName(d.Get("name"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("name"); !isEmptyValue(reflect.ValueOf(nameProp)) && (ok || !reflect.DeepEqual(v, nameProp)) { + obj["name"] = nameProp + } + displayNameProp, err := expandIdentityPlatformTenantInboundSamlConfigDisplayName(d.Get("display_name"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("display_name"); !isEmptyValue(reflect.ValueOf(displayNameProp)) && (ok || !reflect.DeepEqual(v, displayNameProp)) { + obj["displayName"] = displayNameProp + } + enabledProp, err := expandIdentityPlatformTenantInboundSamlConfigEnabled(d.Get("enabled"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("enabled"); !isEmptyValue(reflect.ValueOf(enabledProp)) && (ok || !reflect.DeepEqual(v, enabledProp)) { + obj["enabled"] = enabledProp + } + idpConfigProp, err := expandIdentityPlatformTenantInboundSamlConfigIdpConfig(d.Get("idp_config"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("idp_config"); !isEmptyValue(reflect.ValueOf(idpConfigProp)) && (ok || !reflect.DeepEqual(v, idpConfigProp)) { + obj["idpConfig"] = idpConfigProp + } + spConfigProp, err := expandIdentityPlatformTenantInboundSamlConfigSpConfig(d.Get("sp_config"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("sp_config"); !isEmptyValue(reflect.ValueOf(spConfigProp)) && (ok || !reflect.DeepEqual(v, spConfigProp)) { + obj["spConfig"] = spConfigProp + } + + url, err := replaceVars(d, config, "{{IdentityPlatformBasePath}}projects/{{project}}/tenants/{{tenant}}/inboundSamlConfigs?inboundSamlConfigId={{name}}") + if err != nil { + return err + } + + log.Printf("[DEBUG] Creating new TenantInboundSamlConfig: %#v", obj) + project, err := getProject(d, config) + if err != nil { + return err + } + res, err := sendRequestWithTimeout(config, "POST", project, url, obj, d.Timeout(schema.TimeoutCreate)) + if err != nil { + return fmt.Errorf("Error creating TenantInboundSamlConfig: %s", err) + } + + // Store the ID now + id, err := replaceVars(d, config, "projects/{{project}}/tenants/{{tenant}}/inboundSamlConfigs/{{name}}") + if err != nil { + return fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + log.Printf("[DEBUG] Finished creating TenantInboundSamlConfig %q: %#v", d.Id(), res) + + return resourceIdentityPlatformTenantInboundSamlConfigRead(d, meta) +} + +func resourceIdentityPlatformTenantInboundSamlConfigRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + url, err := replaceVars(d, config, "{{IdentityPlatformBasePath}}projects/{{project}}/tenants/{{tenant}}/inboundSamlConfigs/{{name}}") + if err != nil { + return err + } + + project, err := getProject(d, config) + if err != nil { + return err + } + res, err := sendRequest(config, "GET", project, url, nil) + if err != nil { + return handleNotFoundError(err, d, fmt.Sprintf("IdentityPlatformTenantInboundSamlConfig %q", d.Id())) + } + + if err := d.Set("project", project); err != nil { + return fmt.Errorf("Error reading TenantInboundSamlConfig: %s", err) + } + + if err := d.Set("name", flattenIdentityPlatformTenantInboundSamlConfigName(res["name"], d)); err != nil { + return fmt.Errorf("Error reading TenantInboundSamlConfig: %s", err) + } + if err := d.Set("display_name", flattenIdentityPlatformTenantInboundSamlConfigDisplayName(res["displayName"], d)); err != nil { + return fmt.Errorf("Error reading TenantInboundSamlConfig: %s", err) + } + if err := d.Set("enabled", flattenIdentityPlatformTenantInboundSamlConfigEnabled(res["enabled"], d)); err != nil { + return fmt.Errorf("Error reading TenantInboundSamlConfig: %s", err) + } + if err := d.Set("idp_config", flattenIdentityPlatformTenantInboundSamlConfigIdpConfig(res["idpConfig"], d)); err != nil { + return fmt.Errorf("Error reading TenantInboundSamlConfig: %s", err) + } + if err := d.Set("sp_config", flattenIdentityPlatformTenantInboundSamlConfigSpConfig(res["spConfig"], d)); err != nil { + return fmt.Errorf("Error reading TenantInboundSamlConfig: %s", err) + } + + return nil +} + +func resourceIdentityPlatformTenantInboundSamlConfigUpdate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + project, err := getProject(d, config) + if err != nil { + return err + } + + obj := make(map[string]interface{}) + displayNameProp, err := expandIdentityPlatformTenantInboundSamlConfigDisplayName(d.Get("display_name"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("display_name"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, displayNameProp)) { + obj["displayName"] = displayNameProp + } + enabledProp, err := expandIdentityPlatformTenantInboundSamlConfigEnabled(d.Get("enabled"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("enabled"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, enabledProp)) { + obj["enabled"] = enabledProp + } + idpConfigProp, err := expandIdentityPlatformTenantInboundSamlConfigIdpConfig(d.Get("idp_config"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("idp_config"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, idpConfigProp)) { + obj["idpConfig"] = idpConfigProp + } + spConfigProp, err := expandIdentityPlatformTenantInboundSamlConfigSpConfig(d.Get("sp_config"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("sp_config"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, spConfigProp)) { + obj["spConfig"] = spConfigProp + } + + url, err := replaceVars(d, config, "{{IdentityPlatformBasePath}}projects/{{project}}/tenants/{{tenant}}/inboundSamlConfigs/{{name}}") + if err != nil { + return err + } + + log.Printf("[DEBUG] Updating TenantInboundSamlConfig %q: %#v", d.Id(), obj) + updateMask := []string{} + + if d.HasChange("display_name") { + updateMask = append(updateMask, "displayName") + } + + if d.HasChange("enabled") { + updateMask = append(updateMask, "enabled") + } + + if d.HasChange("idp_config") { + updateMask = append(updateMask, "idpConfig") + } + + if d.HasChange("sp_config") { + updateMask = append(updateMask, "spConfig") + } + // updateMask is a URL parameter but not present in the schema, so replaceVars + // won't set it + url, err = addQueryParams(url, map[string]string{"updateMask": strings.Join(updateMask, ",")}) + if err != nil { + return err + } + _, err = sendRequestWithTimeout(config, "PATCH", project, url, obj, d.Timeout(schema.TimeoutUpdate)) + + if err != nil { + return fmt.Errorf("Error updating TenantInboundSamlConfig %q: %s", d.Id(), err) + } + + return resourceIdentityPlatformTenantInboundSamlConfigRead(d, meta) +} + +func resourceIdentityPlatformTenantInboundSamlConfigDelete(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + project, err := getProject(d, config) + if err != nil { + return err + } + + url, err := replaceVars(d, config, "{{IdentityPlatformBasePath}}projects/{{project}}/tenants/{{tenant}}/inboundSamlConfigs/{{name}}") + if err != nil { + return err + } + + var obj map[string]interface{} + log.Printf("[DEBUG] Deleting TenantInboundSamlConfig %q", d.Id()) + + res, err := sendRequestWithTimeout(config, "DELETE", project, url, obj, d.Timeout(schema.TimeoutDelete)) + if err != nil { + return handleNotFoundError(err, d, "TenantInboundSamlConfig") + } + + log.Printf("[DEBUG] Finished deleting TenantInboundSamlConfig %q: %#v", d.Id(), res) + return nil +} + +func resourceIdentityPlatformTenantInboundSamlConfigImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + config := meta.(*Config) + if err := parseImportId([]string{ + "projects/(?P[^/]+)/tenants/(?P[^/]+)/inboundSamlConfigs/(?P[^/]+)", + "(?P[^/]+)/(?P[^/]+)/(?P[^/]+)", + "(?P[^/]+)/(?P[^/]+)", + }, d, config); err != nil { + return nil, err + } + + // Replace import id for the resource id + id, err := replaceVars(d, config, "projects/{{project}}/tenants/{{tenant}}/inboundSamlConfigs/{{name}}") + if err != nil { + return nil, fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + return []*schema.ResourceData{d}, nil +} + +func flattenIdentityPlatformTenantInboundSamlConfigName(v interface{}, d *schema.ResourceData) interface{} { + if v == nil { + return v + } + return NameFromSelfLinkStateFunc(v) +} + +func flattenIdentityPlatformTenantInboundSamlConfigDisplayName(v interface{}, d *schema.ResourceData) interface{} { + return v +} + +func flattenIdentityPlatformTenantInboundSamlConfigEnabled(v interface{}, d *schema.ResourceData) interface{} { + return v +} + +func flattenIdentityPlatformTenantInboundSamlConfigIdpConfig(v interface{}, d *schema.ResourceData) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["idp_entity_id"] = + flattenIdentityPlatformTenantInboundSamlConfigIdpConfigIdpEntityId(original["idpEntityId"], d) + transformed["sso_url"] = + flattenIdentityPlatformTenantInboundSamlConfigIdpConfigSsoUrl(original["ssoUrl"], d) + transformed["sign_request"] = + flattenIdentityPlatformTenantInboundSamlConfigIdpConfigSignRequest(original["signRequest"], d) + transformed["idp_certificates"] = + flattenIdentityPlatformTenantInboundSamlConfigIdpConfigIdpCertificates(original["idpCertificates"], d) + return []interface{}{transformed} +} +func flattenIdentityPlatformTenantInboundSamlConfigIdpConfigIdpEntityId(v interface{}, d *schema.ResourceData) interface{} { + return v +} + +func flattenIdentityPlatformTenantInboundSamlConfigIdpConfigSsoUrl(v interface{}, d *schema.ResourceData) interface{} { + return v +} + +func flattenIdentityPlatformTenantInboundSamlConfigIdpConfigSignRequest(v interface{}, d *schema.ResourceData) interface{} { + return v +} + +func flattenIdentityPlatformTenantInboundSamlConfigIdpConfigIdpCertificates(v interface{}, d *schema.ResourceData) interface{} { + if v == nil { + return v + } + l := v.([]interface{}) + transformed := make([]interface{}, 0, len(l)) + for _, raw := range l { + original := raw.(map[string]interface{}) + if len(original) < 1 { + // Do not include empty json objects coming back from the api + continue + } + transformed = append(transformed, map[string]interface{}{ + "x509_certificate": flattenIdentityPlatformTenantInboundSamlConfigIdpConfigIdpCertificatesX509Certificate(original["x509Certificate"], d), + }) + } + return transformed +} +func flattenIdentityPlatformTenantInboundSamlConfigIdpConfigIdpCertificatesX509Certificate(v interface{}, d *schema.ResourceData) interface{} { + return v +} + +func flattenIdentityPlatformTenantInboundSamlConfigSpConfig(v interface{}, d *schema.ResourceData) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["sp_entity_id"] = + flattenIdentityPlatformTenantInboundSamlConfigSpConfigSpEntityId(original["spEntityId"], d) + transformed["callback_uri"] = + flattenIdentityPlatformTenantInboundSamlConfigSpConfigCallbackUri(original["callbackUri"], d) + transformed["sp_certificates"] = + flattenIdentityPlatformTenantInboundSamlConfigSpConfigSpCertificates(original["spCertificates"], d) + return []interface{}{transformed} +} +func flattenIdentityPlatformTenantInboundSamlConfigSpConfigSpEntityId(v interface{}, d *schema.ResourceData) interface{} { + return v +} + +func flattenIdentityPlatformTenantInboundSamlConfigSpConfigCallbackUri(v interface{}, d *schema.ResourceData) interface{} { + return v +} + +func flattenIdentityPlatformTenantInboundSamlConfigSpConfigSpCertificates(v interface{}, d *schema.ResourceData) interface{} { + if v == nil { + return v + } + l := v.([]interface{}) + transformed := make([]interface{}, 0, len(l)) + for _, raw := range l { + original := raw.(map[string]interface{}) + if len(original) < 1 { + // Do not include empty json objects coming back from the api + continue + } + transformed = append(transformed, map[string]interface{}{ + "x509_certificate": flattenIdentityPlatformTenantInboundSamlConfigSpConfigSpCertificatesX509Certificate(original["x509Certificate"], d), + }) + } + return transformed +} +func flattenIdentityPlatformTenantInboundSamlConfigSpConfigSpCertificatesX509Certificate(v interface{}, d *schema.ResourceData) interface{} { + return v +} + +func expandIdentityPlatformTenantInboundSamlConfigName(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandIdentityPlatformTenantInboundSamlConfigDisplayName(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandIdentityPlatformTenantInboundSamlConfigEnabled(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandIdentityPlatformTenantInboundSamlConfigIdpConfig(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 || l[0] == nil { + return nil, nil + } + raw := l[0] + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedIdpEntityId, err := expandIdentityPlatformTenantInboundSamlConfigIdpConfigIdpEntityId(original["idp_entity_id"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedIdpEntityId); val.IsValid() && !isEmptyValue(val) { + transformed["idpEntityId"] = transformedIdpEntityId + } + + transformedSsoUrl, err := expandIdentityPlatformTenantInboundSamlConfigIdpConfigSsoUrl(original["sso_url"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedSsoUrl); val.IsValid() && !isEmptyValue(val) { + transformed["ssoUrl"] = transformedSsoUrl + } + + transformedSignRequest, err := expandIdentityPlatformTenantInboundSamlConfigIdpConfigSignRequest(original["sign_request"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedSignRequest); val.IsValid() && !isEmptyValue(val) { + transformed["signRequest"] = transformedSignRequest + } + + transformedIdpCertificates, err := expandIdentityPlatformTenantInboundSamlConfigIdpConfigIdpCertificates(original["idp_certificates"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedIdpCertificates); val.IsValid() && !isEmptyValue(val) { + transformed["idpCertificates"] = transformedIdpCertificates + } + + return transformed, nil +} + +func expandIdentityPlatformTenantInboundSamlConfigIdpConfigIdpEntityId(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandIdentityPlatformTenantInboundSamlConfigIdpConfigSsoUrl(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandIdentityPlatformTenantInboundSamlConfigIdpConfigSignRequest(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandIdentityPlatformTenantInboundSamlConfigIdpConfigIdpCertificates(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + l := v.([]interface{}) + req := make([]interface{}, 0, len(l)) + for _, raw := range l { + if raw == nil { + continue + } + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedX509Certificate, err := expandIdentityPlatformTenantInboundSamlConfigIdpConfigIdpCertificatesX509Certificate(original["x509_certificate"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedX509Certificate); val.IsValid() && !isEmptyValue(val) { + transformed["x509Certificate"] = transformedX509Certificate + } + + req = append(req, transformed) + } + return req, nil +} + +func expandIdentityPlatformTenantInboundSamlConfigIdpConfigIdpCertificatesX509Certificate(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandIdentityPlatformTenantInboundSamlConfigSpConfig(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 || l[0] == nil { + return nil, nil + } + raw := l[0] + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedSpEntityId, err := expandIdentityPlatformTenantInboundSamlConfigSpConfigSpEntityId(original["sp_entity_id"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedSpEntityId); val.IsValid() && !isEmptyValue(val) { + transformed["spEntityId"] = transformedSpEntityId + } + + transformedCallbackUri, err := expandIdentityPlatformTenantInboundSamlConfigSpConfigCallbackUri(original["callback_uri"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedCallbackUri); val.IsValid() && !isEmptyValue(val) { + transformed["callbackUri"] = transformedCallbackUri + } + + transformedSpCertificates, err := expandIdentityPlatformTenantInboundSamlConfigSpConfigSpCertificates(original["sp_certificates"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedSpCertificates); val.IsValid() && !isEmptyValue(val) { + transformed["spCertificates"] = transformedSpCertificates + } + + return transformed, nil +} + +func expandIdentityPlatformTenantInboundSamlConfigSpConfigSpEntityId(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandIdentityPlatformTenantInboundSamlConfigSpConfigCallbackUri(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandIdentityPlatformTenantInboundSamlConfigSpConfigSpCertificates(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + l := v.([]interface{}) + req := make([]interface{}, 0, len(l)) + for _, raw := range l { + if raw == nil { + continue + } + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedX509Certificate, err := expandIdentityPlatformTenantInboundSamlConfigSpConfigSpCertificatesX509Certificate(original["x509_certificate"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedX509Certificate); val.IsValid() && !isEmptyValue(val) { + transformed["x509Certificate"] = transformedX509Certificate + } + + req = append(req, transformed) + } + return req, nil +} + +func expandIdentityPlatformTenantInboundSamlConfigSpConfigSpCertificatesX509Certificate(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} diff --git a/google/resource_identity_platform_tenant_inbound_saml_config_generated_test.go b/google/resource_identity_platform_tenant_inbound_saml_config_generated_test.go new file mode 100644 index 00000000000..69d11a0c004 --- /dev/null +++ b/google/resource_identity_platform_tenant_inbound_saml_config_generated_test.go @@ -0,0 +1,102 @@ +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file in +// .github/CONTRIBUTING.md. +// +// ---------------------------------------------------------------------------- + +package google + +import ( + "fmt" + "strings" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/terraform" +) + +func TestAccIdentityPlatformTenantInboundSamlConfig_identityPlatformTenantInboundSamlConfigBasicExample(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(10), + } + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckIdentityPlatformTenantInboundSamlConfigDestroy, + Steps: []resource.TestStep{ + { + Config: testAccIdentityPlatformTenantInboundSamlConfig_identityPlatformTenantInboundSamlConfigBasicExample(context), + }, + { + ResourceName: "google_identity_platform_tenant_inbound_saml_config.tenant_saml_config", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"tenant"}, + }, + }, + }) +} + +func testAccIdentityPlatformTenantInboundSamlConfig_identityPlatformTenantInboundSamlConfigBasicExample(context map[string]interface{}) string { + return Nprintf(` +resource "google_identity_platform_tenant" "tenant" { + display_name = "tenant" +} + +resource "google_identity_platform_tenant_inbound_saml_config" "tenant_saml_config" { + name = "saml.tf-config%{random_suffix}" + display_name = "Display Name" + tenant = google_identity_platform_tenant.tenant.name + idp_config { + idp_entity_id = "tf-idp%{random_suffix}" + sign_request = true + sso_url = "example.com" + idp_certificates { + x509_certificate = file("test-fixtures/rsa_cert.pem") + } + } + + sp_config { + sp_entity_id = "tf-sp%{random_suffix}" + callback_uri = "https://example.com" + } +} +`, context) +} + +func testAccCheckIdentityPlatformTenantInboundSamlConfigDestroy(s *terraform.State) error { + for name, rs := range s.RootModule().Resources { + if rs.Type != "google_identity_platform_tenant_inbound_saml_config" { + continue + } + if strings.HasPrefix(name, "data.") { + continue + } + + config := testAccProvider.Meta().(*Config) + + url, err := replaceVarsForTest(config, rs, "{{IdentityPlatformBasePath}}projects/{{project}}/tenants/{{tenant}}/inboundSamlConfigs/{{name}}") + if err != nil { + return err + } + + _, err = sendRequest(config, "GET", "", url, nil) + if err == nil { + return fmt.Errorf("IdentityPlatformTenantInboundSamlConfig still exists at %s", url) + } + } + + return nil +} diff --git a/google/resource_identity_platform_tenant_oauth_idp_config.go b/google/resource_identity_platform_tenant_oauth_idp_config.go new file mode 100644 index 00000000000..dd1274ac25e --- /dev/null +++ b/google/resource_identity_platform_tenant_oauth_idp_config.go @@ -0,0 +1,379 @@ +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file in +// .github/CONTRIBUTING.md. +// +// ---------------------------------------------------------------------------- + +package google + +import ( + "fmt" + "log" + "reflect" + "strings" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" +) + +func resourceIdentityPlatformTenantOauthIdpConfig() *schema.Resource { + return &schema.Resource{ + Create: resourceIdentityPlatformTenantOauthIdpConfigCreate, + Read: resourceIdentityPlatformTenantOauthIdpConfigRead, + Update: resourceIdentityPlatformTenantOauthIdpConfigUpdate, + Delete: resourceIdentityPlatformTenantOauthIdpConfigDelete, + + Importer: &schema.ResourceImporter{ + State: resourceIdentityPlatformTenantOauthIdpConfigImport, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(4 * time.Minute), + Update: schema.DefaultTimeout(4 * time.Minute), + Delete: schema.DefaultTimeout(4 * time.Minute), + }, + + Schema: map[string]*schema.Schema{ + "client_id": { + Type: schema.TypeString, + Required: true, + Description: `The client id of an OAuth client.`, + }, + "display_name": { + Type: schema.TypeString, + Required: true, + Description: `Human friendly display name.`, + }, + "issuer": { + Type: schema.TypeString, + Required: true, + Description: `For OIDC Idps, the issuer identifier.`, + }, + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `The name of the OauthIdpConfig. Must start with 'oidc.'.`, + }, + "tenant": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `The name of the tenant where this OIDC IDP configuration resource exists`, + }, + "client_secret": { + Type: schema.TypeString, + Optional: true, + Description: `The client secret of the OAuth client, to enable OIDC code flow.`, + }, + "enabled": { + Type: schema.TypeBool, + Optional: true, + Description: `If this config allows users to sign in with the provider.`, + }, + "project": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + }, + }, + } +} + +func resourceIdentityPlatformTenantOauthIdpConfigCreate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + obj := make(map[string]interface{}) + nameProp, err := expandIdentityPlatformTenantOauthIdpConfigName(d.Get("name"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("name"); !isEmptyValue(reflect.ValueOf(nameProp)) && (ok || !reflect.DeepEqual(v, nameProp)) { + obj["name"] = nameProp + } + displayNameProp, err := expandIdentityPlatformTenantOauthIdpConfigDisplayName(d.Get("display_name"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("display_name"); !isEmptyValue(reflect.ValueOf(displayNameProp)) && (ok || !reflect.DeepEqual(v, displayNameProp)) { + obj["displayName"] = displayNameProp + } + enabledProp, err := expandIdentityPlatformTenantOauthIdpConfigEnabled(d.Get("enabled"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("enabled"); !isEmptyValue(reflect.ValueOf(enabledProp)) && (ok || !reflect.DeepEqual(v, enabledProp)) { + obj["enabled"] = enabledProp + } + issuerProp, err := expandIdentityPlatformTenantOauthIdpConfigIssuer(d.Get("issuer"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("issuer"); !isEmptyValue(reflect.ValueOf(issuerProp)) && (ok || !reflect.DeepEqual(v, issuerProp)) { + obj["issuer"] = issuerProp + } + clientIdProp, err := expandIdentityPlatformTenantOauthIdpConfigClientId(d.Get("client_id"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("client_id"); !isEmptyValue(reflect.ValueOf(clientIdProp)) && (ok || !reflect.DeepEqual(v, clientIdProp)) { + obj["clientId"] = clientIdProp + } + clientSecretProp, err := expandIdentityPlatformTenantOauthIdpConfigClientSecret(d.Get("client_secret"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("client_secret"); !isEmptyValue(reflect.ValueOf(clientSecretProp)) && (ok || !reflect.DeepEqual(v, clientSecretProp)) { + obj["clientSecret"] = clientSecretProp + } + + url, err := replaceVars(d, config, "{{IdentityPlatformBasePath}}projects/{{project}}/tenants/{{tenant}}/oauthIdpConfigs?oauthIdpConfigId={{name}}") + if err != nil { + return err + } + + log.Printf("[DEBUG] Creating new TenantOauthIdpConfig: %#v", obj) + project, err := getProject(d, config) + if err != nil { + return err + } + res, err := sendRequestWithTimeout(config, "POST", project, url, obj, d.Timeout(schema.TimeoutCreate)) + if err != nil { + return fmt.Errorf("Error creating TenantOauthIdpConfig: %s", err) + } + + // Store the ID now + id, err := replaceVars(d, config, "projects/{{project}}/tenants/{{tenant}}/oauthIdpConfigs/{{name}}") + if err != nil { + return fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + log.Printf("[DEBUG] Finished creating TenantOauthIdpConfig %q: %#v", d.Id(), res) + + return resourceIdentityPlatformTenantOauthIdpConfigRead(d, meta) +} + +func resourceIdentityPlatformTenantOauthIdpConfigRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + url, err := replaceVars(d, config, "{{IdentityPlatformBasePath}}projects/{{project}}/tenants/{{tenant}}/oauthIdpConfigs/{{name}}") + if err != nil { + return err + } + + project, err := getProject(d, config) + if err != nil { + return err + } + res, err := sendRequest(config, "GET", project, url, nil) + if err != nil { + return handleNotFoundError(err, d, fmt.Sprintf("IdentityPlatformTenantOauthIdpConfig %q", d.Id())) + } + + if err := d.Set("project", project); err != nil { + return fmt.Errorf("Error reading TenantOauthIdpConfig: %s", err) + } + + if err := d.Set("name", flattenIdentityPlatformTenantOauthIdpConfigName(res["name"], d)); err != nil { + return fmt.Errorf("Error reading TenantOauthIdpConfig: %s", err) + } + if err := d.Set("display_name", flattenIdentityPlatformTenantOauthIdpConfigDisplayName(res["displayName"], d)); err != nil { + return fmt.Errorf("Error reading TenantOauthIdpConfig: %s", err) + } + if err := d.Set("enabled", flattenIdentityPlatformTenantOauthIdpConfigEnabled(res["enabled"], d)); err != nil { + return fmt.Errorf("Error reading TenantOauthIdpConfig: %s", err) + } + if err := d.Set("issuer", flattenIdentityPlatformTenantOauthIdpConfigIssuer(res["issuer"], d)); err != nil { + return fmt.Errorf("Error reading TenantOauthIdpConfig: %s", err) + } + if err := d.Set("client_id", flattenIdentityPlatformTenantOauthIdpConfigClientId(res["clientId"], d)); err != nil { + return fmt.Errorf("Error reading TenantOauthIdpConfig: %s", err) + } + if err := d.Set("client_secret", flattenIdentityPlatformTenantOauthIdpConfigClientSecret(res["clientSecret"], d)); err != nil { + return fmt.Errorf("Error reading TenantOauthIdpConfig: %s", err) + } + + return nil +} + +func resourceIdentityPlatformTenantOauthIdpConfigUpdate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + project, err := getProject(d, config) + if err != nil { + return err + } + + obj := make(map[string]interface{}) + displayNameProp, err := expandIdentityPlatformTenantOauthIdpConfigDisplayName(d.Get("display_name"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("display_name"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, displayNameProp)) { + obj["displayName"] = displayNameProp + } + enabledProp, err := expandIdentityPlatformTenantOauthIdpConfigEnabled(d.Get("enabled"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("enabled"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, enabledProp)) { + obj["enabled"] = enabledProp + } + issuerProp, err := expandIdentityPlatformTenantOauthIdpConfigIssuer(d.Get("issuer"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("issuer"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, issuerProp)) { + obj["issuer"] = issuerProp + } + clientIdProp, err := expandIdentityPlatformTenantOauthIdpConfigClientId(d.Get("client_id"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("client_id"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, clientIdProp)) { + obj["clientId"] = clientIdProp + } + clientSecretProp, err := expandIdentityPlatformTenantOauthIdpConfigClientSecret(d.Get("client_secret"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("client_secret"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, clientSecretProp)) { + obj["clientSecret"] = clientSecretProp + } + + url, err := replaceVars(d, config, "{{IdentityPlatformBasePath}}projects/{{project}}/tenants/{{tenant}}/oauthIdpConfigs/{{name}}") + if err != nil { + return err + } + + log.Printf("[DEBUG] Updating TenantOauthIdpConfig %q: %#v", d.Id(), obj) + updateMask := []string{} + + if d.HasChange("display_name") { + updateMask = append(updateMask, "displayName") + } + + if d.HasChange("enabled") { + updateMask = append(updateMask, "enabled") + } + + if d.HasChange("issuer") { + updateMask = append(updateMask, "issuer") + } + + if d.HasChange("client_id") { + updateMask = append(updateMask, "clientId") + } + + if d.HasChange("client_secret") { + updateMask = append(updateMask, "clientSecret") + } + // updateMask is a URL parameter but not present in the schema, so replaceVars + // won't set it + url, err = addQueryParams(url, map[string]string{"updateMask": strings.Join(updateMask, ",")}) + if err != nil { + return err + } + _, err = sendRequestWithTimeout(config, "PATCH", project, url, obj, d.Timeout(schema.TimeoutUpdate)) + + if err != nil { + return fmt.Errorf("Error updating TenantOauthIdpConfig %q: %s", d.Id(), err) + } + + return resourceIdentityPlatformTenantOauthIdpConfigRead(d, meta) +} + +func resourceIdentityPlatformTenantOauthIdpConfigDelete(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + project, err := getProject(d, config) + if err != nil { + return err + } + + url, err := replaceVars(d, config, "{{IdentityPlatformBasePath}}projects/{{project}}/tenants/{{tenant}}/oauthIdpConfigs/{{name}}") + if err != nil { + return err + } + + var obj map[string]interface{} + log.Printf("[DEBUG] Deleting TenantOauthIdpConfig %q", d.Id()) + + res, err := sendRequestWithTimeout(config, "DELETE", project, url, obj, d.Timeout(schema.TimeoutDelete)) + if err != nil { + return handleNotFoundError(err, d, "TenantOauthIdpConfig") + } + + log.Printf("[DEBUG] Finished deleting TenantOauthIdpConfig %q: %#v", d.Id(), res) + return nil +} + +func resourceIdentityPlatformTenantOauthIdpConfigImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + config := meta.(*Config) + if err := parseImportId([]string{ + "projects/(?P[^/]+)/tenants/(?P[^/]+)/oauthIdpConfigs/(?P[^/]+)", + "(?P[^/]+)/(?P[^/]+)/(?P[^/]+)", + "(?P[^/]+)/(?P[^/]+)", + }, d, config); err != nil { + return nil, err + } + + // Replace import id for the resource id + id, err := replaceVars(d, config, "projects/{{project}}/tenants/{{tenant}}/oauthIdpConfigs/{{name}}") + if err != nil { + return nil, fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + return []*schema.ResourceData{d}, nil +} + +func flattenIdentityPlatformTenantOauthIdpConfigName(v interface{}, d *schema.ResourceData) interface{} { + if v == nil { + return v + } + return NameFromSelfLinkStateFunc(v) +} + +func flattenIdentityPlatformTenantOauthIdpConfigDisplayName(v interface{}, d *schema.ResourceData) interface{} { + return v +} + +func flattenIdentityPlatformTenantOauthIdpConfigEnabled(v interface{}, d *schema.ResourceData) interface{} { + return v +} + +func flattenIdentityPlatformTenantOauthIdpConfigIssuer(v interface{}, d *schema.ResourceData) interface{} { + return v +} + +func flattenIdentityPlatformTenantOauthIdpConfigClientId(v interface{}, d *schema.ResourceData) interface{} { + return v +} + +func flattenIdentityPlatformTenantOauthIdpConfigClientSecret(v interface{}, d *schema.ResourceData) interface{} { + return v +} + +func expandIdentityPlatformTenantOauthIdpConfigName(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandIdentityPlatformTenantOauthIdpConfigDisplayName(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandIdentityPlatformTenantOauthIdpConfigEnabled(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandIdentityPlatformTenantOauthIdpConfigIssuer(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandIdentityPlatformTenantOauthIdpConfigClientId(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandIdentityPlatformTenantOauthIdpConfigClientSecret(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} diff --git a/google/resource_identity_platform_tenant_oauth_idp_config_generated_test.go b/google/resource_identity_platform_tenant_oauth_idp_config_generated_test.go new file mode 100644 index 00000000000..64e2a5044f1 --- /dev/null +++ b/google/resource_identity_platform_tenant_oauth_idp_config_generated_test.go @@ -0,0 +1,93 @@ +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file in +// .github/CONTRIBUTING.md. +// +// ---------------------------------------------------------------------------- + +package google + +import ( + "fmt" + "strings" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/terraform" +) + +func TestAccIdentityPlatformTenantOauthIdpConfig_identityPlatformTenantOauthIdpConfigBasicExample(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(10), + } + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckIdentityPlatformTenantOauthIdpConfigDestroy, + Steps: []resource.TestStep{ + { + Config: testAccIdentityPlatformTenantOauthIdpConfig_identityPlatformTenantOauthIdpConfigBasicExample(context), + }, + { + ResourceName: "google_identity_platform_tenant_oauth_idp_config.tenant_oauth_idp_config", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"tenant"}, + }, + }, + }) +} + +func testAccIdentityPlatformTenantOauthIdpConfig_identityPlatformTenantOauthIdpConfigBasicExample(context map[string]interface{}) string { + return Nprintf(` +resource "google_identity_platform_tenant" "tenant" { + display_name = "tenant" +} + +resource "google_identity_platform_tenant_oauth_idp_config" "tenant_oauth_idp_config" { + name = "oidc.oauth-idp-config%{random_suffix}" + tenant = google_identity_platform_tenant.tenant.name + display_name = "Display Name" + client_id = "client-id" + issuer = "issuer" + enabled = true + client_secret = "secret" +} +`, context) +} + +func testAccCheckIdentityPlatformTenantOauthIdpConfigDestroy(s *terraform.State) error { + for name, rs := range s.RootModule().Resources { + if rs.Type != "google_identity_platform_tenant_oauth_idp_config" { + continue + } + if strings.HasPrefix(name, "data.") { + continue + } + + config := testAccProvider.Meta().(*Config) + + url, err := replaceVarsForTest(config, rs, "{{IdentityPlatformBasePath}}projects/{{project}}/tenants/{{tenant}}/oauthIdpConfigs/{{name}}") + if err != nil { + return err + } + + _, err = sendRequest(config, "GET", "", url, nil) + if err == nil { + return fmt.Errorf("IdentityPlatformTenantOauthIdpConfig still exists at %s", url) + } + } + + return nil +} diff --git a/website/docs/r/identity_platform_default_supported_idp_config.html.markdown b/website/docs/r/identity_platform_default_supported_idp_config.html.markdown new file mode 100644 index 00000000000..e99e406bf4e --- /dev/null +++ b/website/docs/r/identity_platform_default_supported_idp_config.html.markdown @@ -0,0 +1,102 @@ +--- +# ---------------------------------------------------------------------------- +# +# *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** +# +# ---------------------------------------------------------------------------- +# +# This file is automatically generated by Magic Modules and manual +# changes will be clobbered when the file is regenerated. +# +# Please read more about how to change this file in +# .github/CONTRIBUTING.md. +# +# ---------------------------------------------------------------------------- +subcategory: "Identity Platform" +layout: "google" +page_title: "Google: google_identity_platform_default_supported_idp_config" +sidebar_current: "docs-google-identity-platform-default-supported-idp-config" +description: |- + Configurations options for authenticating with a the standard set of Identity Toolkit-trusted IDPs. +--- + +# google\_identity\_platform\_default\_supported\_idp\_config + +Configurations options for authenticating with a the standard set of Identity Toolkit-trusted IDPs. + +You must enable the +((Google Identity Platform)[https://console.cloud.google.com/marketplace/details/google-cloud-platform/customer-identity]) +in the marketplace prior to using this resource. + + + +## Example Usage - Identity Platform Default Supported Idp Config Basic + + +```hcl +resource "google_identity_platform_default_supported_idp_config" "idp_config" { + enabled = true + client_id = "playgames.google.com" + client_secret = "secret" +} +``` + +## Argument Reference + +The following arguments are supported: + + +* `client_id` - + (Required) + OAuth client ID + +* `client_secret` - + (Required) + OAuth client secret + + +- - - + + +* `enabled` - + (Optional) + If this IDP allows the user to sign in + +* `project` - (Optional) The ID of the project in which the resource belongs. + If it is not provided, the provider project is used. + + +## Attributes Reference + +In addition to the arguments listed above, the following computed attributes are exported: + + +* `name` - + The name of the DefaultSupportedIdpConfig resource + + +## Timeouts + +This resource provides the following +[Timeouts](/docs/configuration/resources.html#timeouts) configuration options: + +- `create` - Default is 4 minutes. +- `update` - Default is 4 minutes. +- `delete` - Default is 4 minutes. + +## Import + +DefaultSupportedIdpConfig can be imported using any of these accepted formats: + +``` +$ terraform import google_identity_platform_default_supported_idp_config.default projects/{{project}}/defaultSupportedIdpConfigs/{{client_id}} +$ terraform import google_identity_platform_default_supported_idp_config.default {{project}}/{{client_id}} +$ terraform import google_identity_platform_default_supported_idp_config.default {{client_id}} +``` + +-> If you're importing a resource with beta features, make sure to include `-provider=google-beta` +as an argument so that Terraform uses the correct provider to import your resource. + +## User Project Overrides + +This resource supports [User Project Overrides](https://www.terraform.io/docs/providers/google/guides/provider_reference.html#user_project_override). diff --git a/website/docs/r/identity_platform_inbound_saml_config.html.markdown b/website/docs/r/identity_platform_inbound_saml_config.html.markdown new file mode 100644 index 00000000000..d4ef5536db2 --- /dev/null +++ b/website/docs/r/identity_platform_inbound_saml_config.html.markdown @@ -0,0 +1,166 @@ +--- +# ---------------------------------------------------------------------------- +# +# *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** +# +# ---------------------------------------------------------------------------- +# +# This file is automatically generated by Magic Modules and manual +# changes will be clobbered when the file is regenerated. +# +# Please read more about how to change this file in +# .github/CONTRIBUTING.md. +# +# ---------------------------------------------------------------------------- +subcategory: "Identity Platform" +layout: "google" +page_title: "Google: google_identity_platform_inbound_saml_config" +sidebar_current: "docs-google-identity-platform-inbound-saml-config" +description: |- + Inbound SAML configuration for a Identity Toolkit project. +--- + +# google\_identity\_platform\_inbound\_saml\_config + +Inbound SAML configuration for a Identity Toolkit project. + +You must enable the +((Google Identity Platform)[https://console.cloud.google.com/marketplace/details/google-cloud-platform/customer-identity]) +in the marketplace prior to using this resource. + + + + +## Example Usage - Identity Platform Inbound Saml Config Basic + + +```hcl +resource "google_identity_platform_inbound_saml_config" "saml_config" { + name = "saml.tf-config" + display_name = "Display Name" + idp_config { + idp_entity_id = "tf-idp" + sign_request = true + sso_url = "example.com" + idp_certificates { + x509_certificate = file("test-fixtures/rsa_cert.pem") + } + } + + sp_config { + sp_entity_id = "tf-sp" + callback_uri = "https://example.com" + } +} +``` + +## Argument Reference + +The following arguments are supported: + + +* `name` - + (Required) + The name of the InboundSamlConfig resource. Must start with 'saml.' and can only have alphanumeric characters, + hyphens, underscores or periods. The part after 'saml.' must also start with a lowercase letter, end with an + alphanumeric character, and have at least 2 characters. + +* `display_name` - + (Required) + Human friendly display name. + +* `idp_config` - + (Required) + SAML IdP configuration when the project acts as the relying party Structure is documented below. + +* `sp_config` - + (Required) + SAML SP (Service Provider) configuration when the project acts as the relying party to receive + and accept an authentication assertion issued by a SAML identity provider. Structure is documented below. + + +The `idp_config` block supports: + +* `idp_entity_id` - + (Required) + Unique identifier for all SAML entities + +* `sso_url` - + (Required) + URL to send Authentication request to. + +* `sign_request` - + (Optional) + Indicates if outbounding SAMLRequest should be signed. + +* `idp_certificates` - + (Required) + The IdP's certificate data to verify the signature in the SAMLResponse issued by the IDP. Structure is documented below. + + +The `idp_certificates` block supports: + +* `x509_certificate` - + (Optional) + The IdP's x509 certificate. + +The `sp_config` block supports: + +* `sp_entity_id` - + (Optional) + Unique identifier for all SAML entities. + +* `callback_uri` - + (Optional) + Callback URI where responses from IDP are handled. Must start with `https://`. + +* `sp_certificates` - + The IDP's certificate data to verify the signature in the SAMLResponse issued by the IDP. Structure is documented below. + + +The `sp_certificates` block contains: + +* `x509_certificate` - + The x509 certificate + +- - - + + +* `enabled` - + (Optional) + If this config allows users to sign in with the provider. + +* `project` - (Optional) The ID of the project in which the resource belongs. + If it is not provided, the provider project is used. + + + +## Timeouts + +This resource provides the following +[Timeouts](/docs/configuration/resources.html#timeouts) configuration options: + +- `create` - Default is 4 minutes. +- `update` - Default is 4 minutes. +- `delete` - Default is 4 minutes. + +## Import + +InboundSamlConfig can be imported using any of these accepted formats: + +``` +$ terraform import google_identity_platform_inbound_saml_config.default projects/{{project}}/inboundSamlConfigs/{{name}} +$ terraform import google_identity_platform_inbound_saml_config.default {{project}}/{{name}} +$ terraform import google_identity_platform_inbound_saml_config.default {{name}} +``` + +-> If you're importing a resource with beta features, make sure to include `-provider=google-beta` +as an argument so that Terraform uses the correct provider to import your resource. + +## User Project Overrides + +This resource supports [User Project Overrides](https://www.terraform.io/docs/providers/google/guides/provider_reference.html#user_project_override). diff --git a/website/docs/r/identity_platform_oauth_idp_config.html.markdown b/website/docs/r/identity_platform_oauth_idp_config.html.markdown new file mode 100644 index 00000000000..37606d3fa6d --- /dev/null +++ b/website/docs/r/identity_platform_oauth_idp_config.html.markdown @@ -0,0 +1,114 @@ +--- +# ---------------------------------------------------------------------------- +# +# *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** +# +# ---------------------------------------------------------------------------- +# +# This file is automatically generated by Magic Modules and manual +# changes will be clobbered when the file is regenerated. +# +# Please read more about how to change this file in +# .github/CONTRIBUTING.md. +# +# ---------------------------------------------------------------------------- +subcategory: "Identity Platform" +layout: "google" +page_title: "Google: google_identity_platform_oauth_idp_config" +sidebar_current: "docs-google-identity-platform-oauth-idp-config" +description: |- + OIDC IdP configuration for a Identity Toolkit project. +--- + +# google\_identity\_platform\_oauth\_idp\_config + +OIDC IdP configuration for a Identity Toolkit project. + +You must enable the +((Google Identity Platform)[https://console.cloud.google.com/marketplace/details/google-cloud-platform/customer-identity]) +in the marketplace prior to using this resource. + + + + +## Example Usage - Identity Platform Oauth Idp Config Basic + + +```hcl +resource "google_identity_platform_oauth_idp_config" "oauth_idp_config" { + name = "oidc.oauth-idp-config" + display_name = "Display Name" + client_id = "client-id" + issuer = "issuer" + enabled = true + client_secret = "secret" +} +``` + +## Argument Reference + +The following arguments are supported: + + +* `name` - + (Required) + The name of the OauthIdpConfig. Must start with `oidc.`. + +* `issuer` - + (Required) + For OIDC Idps, the issuer identifier. + +* `client_id` - + (Required) + The client id of an OAuth client. + + +- - - + + +* `display_name` - + (Optional) + Human friendly display name. + +* `enabled` - + (Optional) + If this config allows users to sign in with the provider. + +* `client_secret` - + (Optional) + The client secret of the OAuth client, to enable OIDC code flow. + +* `project` - (Optional) The ID of the project in which the resource belongs. + If it is not provided, the provider project is used. + + + +## Timeouts + +This resource provides the following +[Timeouts](/docs/configuration/resources.html#timeouts) configuration options: + +- `create` - Default is 4 minutes. +- `update` - Default is 4 minutes. +- `delete` - Default is 4 minutes. + +## Import + +OauthIdpConfig can be imported using any of these accepted formats: + +``` +$ terraform import google_identity_platform_oauth_idp_config.default projects/{{project}}/oauthIdpConfigs/{{name}} +$ terraform import google_identity_platform_oauth_idp_config.default {{project}}/{{name}} +$ terraform import google_identity_platform_oauth_idp_config.default {{name}} +``` + +-> If you're importing a resource with beta features, make sure to include `-provider=google-beta` +as an argument so that Terraform uses the correct provider to import your resource. + +## User Project Overrides + +This resource supports [User Project Overrides](https://www.terraform.io/docs/providers/google/guides/provider_reference.html#user_project_override). diff --git a/website/docs/r/identity_platform_tenant.html.markdown b/website/docs/r/identity_platform_tenant.html.markdown new file mode 100644 index 00000000000..ee411910030 --- /dev/null +++ b/website/docs/r/identity_platform_tenant.html.markdown @@ -0,0 +1,115 @@ +--- +# ---------------------------------------------------------------------------- +# +# *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** +# +# ---------------------------------------------------------------------------- +# +# This file is automatically generated by Magic Modules and manual +# changes will be clobbered when the file is regenerated. +# +# Please read more about how to change this file in +# .github/CONTRIBUTING.md. +# +# ---------------------------------------------------------------------------- +subcategory: "Identity Platform" +layout: "google" +page_title: "Google: google_identity_platform_tenant" +sidebar_current: "docs-google-identity-platform-tenant" +description: |- + Tenant configuration in a multi-tenant project. +--- + +# google\_identity\_platform\_tenant + +Tenant configuration in a multi-tenant project. + +You must enable the +((Google Identity Platform)[https://console.cloud.google.com/marketplace/details/google-cloud-platform/customer-identity]) +in the marketplace prior to using this resource. + +You must ((enable multi-tenancy)[https://cloud.google.com/identity-platform/docs/multi-tenancy-quickstart]) +via the Cloud Console prior to creating tenants. + + + + +## Example Usage - Identity Platform Tenant Basic + + +```hcl +resource "google_identity_platform_tenant" "tenant" { + display_name = "tenant" + allow_password_signup = true +} +``` + +## Argument Reference + +The following arguments are supported: + + +* `display_name` - + (Required) + Human friendly display name of the tenant. + + +- - - + + +* `allow_password_signup` - + (Optional) + Whether to allow email/password user authentication. + +* `enable_email_link_signin` - + (Optional) + Whether to enable email link user authentication. + +* `disable_auth` - + (Optional) + Whether authentication is disabled for the tenant. If true, the users under + the disabled tenant are not allowed to sign-in. Admins of the disabled tenant + are not able to manage its users. + +* `project` - (Optional) The ID of the project in which the resource belongs. + If it is not provided, the provider project is used. + + +## Attributes Reference + +In addition to the arguments listed above, the following computed attributes are exported: + + +* `name` - + The name of the tenant that is generated by the server + + +## Timeouts + +This resource provides the following +[Timeouts](/docs/configuration/resources.html#timeouts) configuration options: + +- `create` - Default is 4 minutes. +- `update` - Default is 4 minutes. +- `delete` - Default is 4 minutes. + +## Import + +Tenant can be imported using any of these accepted formats: + +``` +$ terraform import google_identity_platform_tenant.default projects/{{project}}/tenants/{{name}} +$ terraform import google_identity_platform_tenant.default {{project}}/{{name}} +$ terraform import google_identity_platform_tenant.default {{name}} +``` + +-> If you're importing a resource with beta features, make sure to include `-provider=google-beta` +as an argument so that Terraform uses the correct provider to import your resource. + +## User Project Overrides + +This resource supports [User Project Overrides](https://www.terraform.io/docs/providers/google/guides/provider_reference.html#user_project_override). diff --git a/website/docs/r/identity_platform_tenant_default_supported_idp_config.html.markdown b/website/docs/r/identity_platform_tenant_default_supported_idp_config.html.markdown new file mode 100644 index 00000000000..dc2ac5addec --- /dev/null +++ b/website/docs/r/identity_platform_tenant_default_supported_idp_config.html.markdown @@ -0,0 +1,116 @@ +--- +# ---------------------------------------------------------------------------- +# +# *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** +# +# ---------------------------------------------------------------------------- +# +# This file is automatically generated by Magic Modules and manual +# changes will be clobbered when the file is regenerated. +# +# Please read more about how to change this file in +# .github/CONTRIBUTING.md. +# +# ---------------------------------------------------------------------------- +subcategory: "Identity Platform" +layout: "google" +page_title: "Google: google_identity_platform_tenant_default_supported_idp_config" +sidebar_current: "docs-google-identity-platform-tenant-default-supported-idp-config" +description: |- + Configurations options for the tenant for authenticating with a the standard set of Identity Toolkit-trusted IDPs. +--- + +# google\_identity\_platform\_tenant\_default\_supported\_idp\_config + +Configurations options for the tenant for authenticating with a the standard set of Identity Toolkit-trusted IDPs. + +You must enable the +((Google Identity Platform)[https://console.cloud.google.com/marketplace/details/google-cloud-platform/customer-identity]) +in the marketplace prior to using this resource. + + + + +## Example Usage - Identity Platform Tenant Default Supported Idp Config Basic + + +```hcl +resource "google_identity_platform_tenant" "tenant" { + display_name = "tenant" +} + +resource "google_identity_platform_tenant_default_supported_idp_config" "idp_config" { + enabled = true + tenant = google_identity_platform_tenant.tenant.name + client_id = "playgames.google.com" + client_secret = "secret" +} +``` + +## Argument Reference + +The following arguments are supported: + + +* `tenant` - + (Required) + The name of the tenant where this DefaultSupportedIdpConfig resource exists + +* `client_id` - + (Required) + OAuth client ID + +* `client_secret` - + (Required) + OAuth client secret + + +- - - + + +* `enabled` - + (Optional) + If this IDP allows the user to sign in + +* `project` - (Optional) The ID of the project in which the resource belongs. + If it is not provided, the provider project is used. + + +## Attributes Reference + +In addition to the arguments listed above, the following computed attributes are exported: + + +* `name` - + The name of the default supported IDP config resource + + +## Timeouts + +This resource provides the following +[Timeouts](/docs/configuration/resources.html#timeouts) configuration options: + +- `create` - Default is 4 minutes. +- `update` - Default is 4 minutes. +- `delete` - Default is 4 minutes. + +## Import + +TenantDefaultSupportedIdpConfig can be imported using any of these accepted formats: + +``` +$ terraform import google_identity_platform_tenant_default_supported_idp_config.default projects/{{project}}/tenants/{{tenant}}/defaultSupportedIdpConfigs/{{client_id}} +$ terraform import google_identity_platform_tenant_default_supported_idp_config.default {{project}}/{{tenant}}/{{client_id}} +$ terraform import google_identity_platform_tenant_default_supported_idp_config.default {{tenant}}/{{client_id}} +``` + +-> If you're importing a resource with beta features, make sure to include `-provider=google-beta` +as an argument so that Terraform uses the correct provider to import your resource. + +## User Project Overrides + +This resource supports [User Project Overrides](https://www.terraform.io/docs/providers/google/guides/provider_reference.html#user_project_override). diff --git a/website/docs/r/identity_platform_tenant_inbound_saml_config.html.markdown b/website/docs/r/identity_platform_tenant_inbound_saml_config.html.markdown new file mode 100644 index 00000000000..b7f897b193d --- /dev/null +++ b/website/docs/r/identity_platform_tenant_inbound_saml_config.html.markdown @@ -0,0 +1,175 @@ +--- +# ---------------------------------------------------------------------------- +# +# *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** +# +# ---------------------------------------------------------------------------- +# +# This file is automatically generated by Magic Modules and manual +# changes will be clobbered when the file is regenerated. +# +# Please read more about how to change this file in +# .github/CONTRIBUTING.md. +# +# ---------------------------------------------------------------------------- +subcategory: "Identity Platform" +layout: "google" +page_title: "Google: google_identity_platform_tenant_inbound_saml_config" +sidebar_current: "docs-google-identity-platform-tenant-inbound-saml-config" +description: |- + Inbound SAML configuration for a Identity Toolkit tenant. +--- + +# google\_identity\_platform\_tenant\_inbound\_saml\_config + +Inbound SAML configuration for a Identity Toolkit tenant. + +You must enable the +((Google Identity Platform)[https://console.cloud.google.com/marketplace/details/google-cloud-platform/customer-identity]) +in the marketplace prior to using this resource. + + + + +## Example Usage - Identity Platform Tenant Inbound Saml Config Basic + + +```hcl +resource "google_identity_platform_tenant" "tenant" { + display_name = "tenant" +} + +resource "google_identity_platform_tenant_inbound_saml_config" "tenant_saml_config" { + name = "saml.tf-config" + display_name = "Display Name" + tenant = google_identity_platform_tenant.tenant.name + idp_config { + idp_entity_id = "tf-idp" + sign_request = true + sso_url = "example.com" + idp_certificates { + x509_certificate = file("test-fixtures/rsa_cert.pem") + } + } + + sp_config { + sp_entity_id = "tf-sp" + callback_uri = "https://example.com" + } +} +``` + +## Argument Reference + +The following arguments are supported: + + +* `name` - + (Required) + The name of the InboundSamlConfig resource. Must start with 'saml.' and can only have alphanumeric characters, + hyphens, underscores or periods. The part after 'saml.' must also start with a lowercase letter, end with an + alphanumeric character, and have at least 2 characters. + +* `tenant` - + (Required) + The name of the tenant where this inbound SAML config resource exists + +* `display_name` - + (Required) + Human friendly display name. + +* `idp_config` - + (Required) + SAML IdP configuration when the project acts as the relying party Structure is documented below. + +* `sp_config` - + (Required) + SAML SP (Service Provider) configuration when the project acts as the relying party to receive + and accept an authentication assertion issued by a SAML identity provider. Structure is documented below. + + +The `idp_config` block supports: + +* `idp_entity_id` - + (Required) + Unique identifier for all SAML entities + +* `sso_url` - + (Required) + URL to send Authentication request to. + +* `sign_request` - + (Optional) + Indicates if outbounding SAMLRequest should be signed. + +* `idp_certificates` - + (Required) + The IDP's certificate data to verify the signature in the SAMLResponse issued by the IDP. Structure is documented below. + + +The `idp_certificates` block supports: + +* `x509_certificate` - + (Optional) + The x509 certificate + +The `sp_config` block supports: + +* `sp_entity_id` - + (Required) + Unique identifier for all SAML entities. + +* `callback_uri` - + (Required) + Callback URI where responses from IDP are handled. Must start with `https://`. + +* `sp_certificates` - + The IDP's certificate data to verify the signature in the SAMLResponse issued by the IDP. Structure is documented below. + + +The `sp_certificates` block contains: + +* `x509_certificate` - + The x509 certificate + +- - - + + +* `enabled` - + (Optional) + If this config allows users to sign in with the provider. + +* `project` - (Optional) The ID of the project in which the resource belongs. + If it is not provided, the provider project is used. + + + +## Timeouts + +This resource provides the following +[Timeouts](/docs/configuration/resources.html#timeouts) configuration options: + +- `create` - Default is 4 minutes. +- `update` - Default is 4 minutes. +- `delete` - Default is 4 minutes. + +## Import + +TenantInboundSamlConfig can be imported using any of these accepted formats: + +``` +$ terraform import google_identity_platform_tenant_inbound_saml_config.default projects/{{project}}/tenants/{{tenant}}/inboundSamlConfigs/{{name}} +$ terraform import google_identity_platform_tenant_inbound_saml_config.default {{project}}/{{tenant}}/{{name}} +$ terraform import google_identity_platform_tenant_inbound_saml_config.default {{tenant}}/{{name}} +``` + +-> If you're importing a resource with beta features, make sure to include `-provider=google-beta` +as an argument so that Terraform uses the correct provider to import your resource. + +## User Project Overrides + +This resource supports [User Project Overrides](https://www.terraform.io/docs/providers/google/guides/provider_reference.html#user_project_override). diff --git a/website/docs/r/identity_platform_tenant_oauth_idp_config.html.markdown b/website/docs/r/identity_platform_tenant_oauth_idp_config.html.markdown new file mode 100644 index 00000000000..341356f91f0 --- /dev/null +++ b/website/docs/r/identity_platform_tenant_oauth_idp_config.html.markdown @@ -0,0 +1,123 @@ +--- +# ---------------------------------------------------------------------------- +# +# *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** +# +# ---------------------------------------------------------------------------- +# +# This file is automatically generated by Magic Modules and manual +# changes will be clobbered when the file is regenerated. +# +# Please read more about how to change this file in +# .github/CONTRIBUTING.md. +# +# ---------------------------------------------------------------------------- +subcategory: "Identity Platform" +layout: "google" +page_title: "Google: google_identity_platform_tenant_oauth_idp_config" +sidebar_current: "docs-google-identity-platform-tenant-oauth-idp-config" +description: |- + OIDC IdP configuration for a Identity Toolkit project within a tenant. +--- + +# google\_identity\_platform\_tenant\_oauth\_idp\_config + +OIDC IdP configuration for a Identity Toolkit project within a tenant. + +You must enable the +((Google Identity Platform)[https://console.cloud.google.com/marketplace/details/google-cloud-platform/customer-identity]) +in the marketplace prior to using this resource. + + + + +## Example Usage - Identity Platform Tenant Oauth Idp Config Basic + + +```hcl +resource "google_identity_platform_tenant" "tenant" { + display_name = "tenant" +} + +resource "google_identity_platform_tenant_oauth_idp_config" "tenant_oauth_idp_config" { + name = "oidc.oauth-idp-config" + tenant = google_identity_platform_tenant.tenant.name + display_name = "Display Name" + client_id = "client-id" + issuer = "issuer" + enabled = true + client_secret = "secret" +} +``` + +## Argument Reference + +The following arguments are supported: + + +* `name` - + (Required) + The name of the OauthIdpConfig. Must start with `oidc.`. + +* `tenant` - + (Required) + The name of the tenant where this OIDC IDP configuration resource exists + +* `display_name` - + (Required) + Human friendly display name. + +* `issuer` - + (Required) + For OIDC Idps, the issuer identifier. + +* `client_id` - + (Required) + The client id of an OAuth client. + + +- - - + + +* `enabled` - + (Optional) + If this config allows users to sign in with the provider. + +* `client_secret` - + (Optional) + The client secret of the OAuth client, to enable OIDC code flow. + +* `project` - (Optional) The ID of the project in which the resource belongs. + If it is not provided, the provider project is used. + + + +## Timeouts + +This resource provides the following +[Timeouts](/docs/configuration/resources.html#timeouts) configuration options: + +- `create` - Default is 4 minutes. +- `update` - Default is 4 minutes. +- `delete` - Default is 4 minutes. + +## Import + +TenantOauthIdpConfig can be imported using any of these accepted formats: + +``` +$ terraform import google_identity_platform_tenant_oauth_idp_config.default projects/{{project}}/tenants/{{tenant}}/oauthIdpConfigs/{{name}} +$ terraform import google_identity_platform_tenant_oauth_idp_config.default {{project}}/{{tenant}}/{{name}} +$ terraform import google_identity_platform_tenant_oauth_idp_config.default {{tenant}}/{{name}} +``` + +-> If you're importing a resource with beta features, make sure to include `-provider=google-beta` +as an argument so that Terraform uses the correct provider to import your resource. + +## User Project Overrides + +This resource supports [User Project Overrides](https://www.terraform.io/docs/providers/google/guides/provider_reference.html#user_project_override). diff --git a/website/google.erb b/website/google.erb index 8a4bddff0be..b5bbe0053de 100644 --- a/website/google.erb +++ b/website/google.erb @@ -925,6 +925,32 @@ + > + Google Identity Platform Resources + + + > Google ML Engine Resources