blob: 97f8d5248c1a6433bcbbbb496722748a43726494 [file] [log] [blame]
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
// ----------------------------------------------------------------------------
//
// *** AUTO GENERATED CODE *** Type: MMv1 ***
//
// ----------------------------------------------------------------------------
//
// 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 firebasehosting
import (
"encoding/json"
"fmt"
"log"
"reflect"
"strings"
"time"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/structure"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
"github.com/hashicorp/terraform-provider-google-beta/google-beta/tpgresource"
transport_tpg "github.com/hashicorp/terraform-provider-google-beta/google-beta/transport"
"github.com/hashicorp/terraform-provider-google-beta/google-beta/verify"
)
func ResourceFirebaseHostingCustomDomain() *schema.Resource {
return &schema.Resource{
Create: resourceFirebaseHostingCustomDomainCreate,
Read: resourceFirebaseHostingCustomDomainRead,
Update: resourceFirebaseHostingCustomDomainUpdate,
Delete: resourceFirebaseHostingCustomDomainDelete,
Importer: &schema.ResourceImporter{
State: resourceFirebaseHostingCustomDomainImport,
},
Timeouts: &schema.ResourceTimeout{
Create: schema.DefaultTimeout(20 * time.Minute),
Update: schema.DefaultTimeout(20 * time.Minute),
Delete: schema.DefaultTimeout(20 * time.Minute),
},
CustomizeDiff: customdiff.All(
tpgresource.DefaultProviderProject,
),
Schema: map[string]*schema.Schema{
"custom_domain": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Description: `The ID of the 'CustomDomain', which is the domain name you'd like to use with Firebase Hosting.`,
},
"site_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Description: `The ID of the site in which to create this custom domain association.`,
},
"cert_preference": {
Type: schema.TypeString,
Computed: true,
Optional: true,
ValidateFunc: verify.ValidateEnum([]string{"GROUPED", "PROJECT_GROUPED", "DEDICATED", ""}),
Description: `A field that lets you specify which SSL certificate type Hosting creates
for your domain name. Spark plan 'CustomDomain's only have access to the
'GROUPED' cert type, while Blaze plan can select any option. Possible values: ["GROUPED", "PROJECT_GROUPED", "DEDICATED"]`,
},
"redirect_target": {
Type: schema.TypeString,
Optional: true,
Description: `A domain name that this CustomDomain should direct traffic towards. If
specified, Hosting will respond to requests against this CustomDomain
with an HTTP 301 code, and route traffic to the specified 'redirect_target'
instead.`,
},
"cert": {
Type: schema.TypeList,
Computed: true,
Description: `The SSL certificate Hosting has for this 'CustomDomain''s domain name.
For new 'CustomDomain's, this often represents Hosting's intent to create
a certificate, rather than an actual cert. Check the 'state' field for
more.`,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"state": {
Type: schema.TypeString,
Optional: true,
Description: `The state of the certificate. Only the 'CERT_ACTIVE' and
'CERT_EXPIRING_SOON' states provide SSL coverage for a domain name. If the
state is 'PROPAGATING' and Hosting had an active cert for the domain name
before, that formerly-active cert provides SSL coverage for the domain name
until the current cert propagates.`,
},
"type": {
Type: schema.TypeString,
Optional: true,
Description: `The certificate's type.`,
},
"verification": {
Type: schema.TypeList,
Optional: true,
Description: `A set of ACME challenges you can add to your DNS records or existing,
non-Hosting hosting provider to allow Hosting to create an SSL certificate
for your domain name before you point traffic toward hosting. You can use
thse challenges as part of a zero downtime transition from your old
provider to Hosting.`,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"dns": {
Type: schema.TypeList,
Optional: true,
Description: `A 'TXT' record to add to your DNS records that confirms your intent to
let Hosting create an SSL cert for your domain name.`,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"desired": {
Type: schema.TypeList,
Optional: true,
Description: `The set of DNS records Hosting needs to serve secure content on the domain.`,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"domain_name": {
Type: schema.TypeString,
Optional: true,
Description: `The domain name the record set pertains to.`,
},
"records": {
Type: schema.TypeList,
Optional: true,
Description: `Records on the domain`,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"domain_name": {
Type: schema.TypeString,
Optional: true,
Description: `The domain name the record pertains to, e.g. 'foo.bar.com.'.`,
},
"rdata": {
Type: schema.TypeString,
Optional: true,
Description: `The data of the record. The meaning of the value depends on record type:
- A and AAAA: IP addresses for the domain name.
- CNAME: Another domain to check for records.
- TXT: Arbitrary text strings associated with the domain name. Hosting
uses TXT records to determine a which Firebase Projects have
permission to act on the domain name's behalf.
- CAA: The record's flags, tag, and value, e.g. '0 issue "pki.goog"'.`,
},
"required_action": {
Type: schema.TypeString,
Optional: true,
Description: `Indicates the a required action for this record.`,
},
"type": {
Type: schema.TypeString,
Optional: true,
Description: `The record's type, which determines what data the record contains.`,
},
},
},
},
},
},
},
"discovered": {
Type: schema.TypeList,
Optional: true,
Description: `The set of DNS records Hosting discovered when inspecting a domain`,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"domain_name": {
Type: schema.TypeString,
Optional: true,
Description: `The domain name the record set pertains to.`,
},
"records": {
Type: schema.TypeList,
Optional: true,
Description: `Records on the domain`,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"domain_name": {
Type: schema.TypeString,
Optional: true,
Description: `The domain name the record pertains to, e.g. 'foo.bar.com.'.`,
},
"rdata": {
Type: schema.TypeString,
Optional: true,
Description: `The data of the record. The meaning of the value depends on record type:
- A and AAAA: IP addresses for the domain name.
- CNAME: Another domain to check for records.
- TXT: Arbitrary text strings associated with the domain name. Hosting
uses TXT records to determine a which Firebase Projects have
permission to act on the domain name's behalf.
- CAA: The record's flags, tag, and value, e.g. '0 issue "pki.goog"'.`,
},
"required_action": {
Type: schema.TypeString,
Optional: true,
Description: `Indicates the a required action for this record.`,
},
"type": {
Type: schema.TypeString,
Optional: true,
Description: `The record's type, which determines what data the record contains.`,
},
},
},
},
},
},
},
"check_time": {
Type: schema.TypeString,
Computed: true,
Description: `The last time Hosting checked your CustomDomain's DNS records.`,
},
},
},
},
"http": {
Type: schema.TypeList,
Optional: true,
Description: `A file to add to your existing, non-Hosting hosting service that confirms
your intent to let Hosting create an SSL cert for your domain name.`,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"desired": {
Type: schema.TypeString,
Optional: true,
Description: `A text string to serve at the path.`,
},
"discovered": {
Type: schema.TypeString,
Optional: true,
Description: `Whether Hosting was able to find the required file contents on the
specified path during its last check.`,
},
"path": {
Type: schema.TypeString,
Optional: true,
Description: `The path to the file.`,
},
"last_check_time": {
Type: schema.TypeString,
Computed: true,
Description: `The last time Hosting systems checked for the file contents.`,
},
},
},
},
},
},
},
},
},
},
"create_time": {
Type: schema.TypeString,
Computed: true,
Description: `The 'CustomDomain''s create time.`,
},
"delete_time": {
Type: schema.TypeString,
Computed: true,
Description: `The time the 'CustomDomain' was deleted; null for 'CustomDomains' that
haven't been deleted. Deleted 'CustomDomains' persist for approximately 30
days, after which time Hosting removes them completely.`,
},
"etag": {
Type: schema.TypeString,
Computed: true,
Description: `A string that represents the current state of the 'CustomDomain' and
allows you to confirm its initial state in requests that would modify it.`,
},
"expire_time": {
Type: schema.TypeString,
Computed: true,
Description: `The minimum time before a soft-deleted 'CustomDomain' is completely removed
from Hosting; null for 'CustomDomains' that haven't been deleted.`,
},
"host_state": {
Type: schema.TypeString,
Computed: true,
Description: `The host state of your domain name. Host state is determined by checking each
IP address associated with your domain name to see if it's serving
Hosting content.
HOST_UNHOSTED:
Your 'CustomDomain''s domain name isn't associated with any IP addresses.
HOST_UNREACHABLE:
Your 'CustomDomain''s domain name can't be reached. Hosting services' DNS
queries to find your domain name's IP addresses resulted in errors. See
your 'CustomDomain''s 'issues' field for more details.
HOST_MISMATCH:
Your 'CustomDomain''s domain name has IP addresses that don't ultimately
resolve to Hosting.
HOST_CONFLICT:
Your 'CustomDomain''s domain name has IP addresses that resolve to both
Hosting and other services. To ensure consistent results, remove 'A' and
'AAAA' records related to non-Hosting services.
HOST_ACTIVE:
All requests against your 'CustomDomain''s domain name are served by
Hosting. If the 'CustomDomain''s 'OwnershipState' is also 'ACTIVE', Hosting
serves your Hosting Site's content on the domain name.`,
},
"issues": {
Type: schema.TypeList,
Computed: true,
Description: `A set of errors Hosting systems encountered when trying to establish
Hosting's ability to serve secure content for your domain name. Resolve
these issues to ensure your 'CustomDomain' behaves properly.`,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"code": {
Type: schema.TypeInt,
Optional: true,
Description: `The status code, which should be an enum value of 'google.rpc.Code'`,
},
"details": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: validation.StringIsJSON,
StateFunc: func(v interface{}) string { s, _ := structure.NormalizeJsonString(v); return s },
Description: `A list of messages that carry the error details.`,
},
"message": {
Type: schema.TypeString,
Optional: true,
Description: `Error message`,
},
},
},
},
"name": {
Type: schema.TypeString,
Computed: true,
Description: `The fully-qualified name of the 'CustomDomain'.`,
},
"ownership_state": {
Type: schema.TypeString,
Computed: true,
Description: `The ownership state of your domain name. Ownership is determined at a
Firebase project level, and established by adding 'TXT' records to your
domain name's DNS records.
Ownership cascades to subdomains. Granting a project ownership of 'foo.com'
also grants that project ownership over 'bar.foo.com', unless you add
specific 'TXT' records to 'bar.foo.com' that grant a different project
ownership.
If your 'CustomDomain' is in an 'OwnershipState' other than
'OWNERSHIP_ACTIVE' for more than 30 days and it hasn't been updated in at
least 30 days, Hosting's ownership systems delete the 'CustomDomain'.
OWNERSHIP_MISSING:
Your 'CustomDomain''s domain name has no Hosting-related ownership records;
no Firebase project has permission to act on the domain name's behalf.
OWNERSHIP_UNREACHABLE:
Your 'CustomDomain''s domain name can't be reached. Hosting services' DNS
queries to find your domain name's ownership records resulted in errors.
See your 'CustomDomain''s 'issues' field for more details.
OWNERSHIP_MISMATCH:
Your 'CustomDomain''s domain name is owned by another Firebase project.
Remove the conflicting 'TXT' records and replace them with project-specific
records for your current Firebase project.
OWNERSHIP_CONFLICT:
Your 'CustomDomain''s domain name has conflicting 'TXT' records that
indicate ownership by both your current Firebase project and another
project. Remove the other project's ownership records to grant the current
project ownership.
OWNERSHIP_PENDING:
Your 'CustomDomain''s DNS records are configured correctly. Hosting will
transfer ownership of your domain to this 'CustomDomain' within 24 hours.
OWNERSHIP_ACTIVE:
Your 'CustomDomain''s domain name has 'TXT' records that grant its project
permission to act on its behalf.`,
},
"reconciling": {
Type: schema.TypeBool,
Computed: true,
Description: `if true, indicates that Hosting's systems are attmepting to
make the 'CustomDomain''s state match your preferred state. This is most
frequently 'true' when initially provisioning a 'CustomDomain' or when creating
a new SSL certificate to match an updated 'cert_preference'`,
},
"required_dns_updates": {
Type: schema.TypeList,
Computed: true,
Description: `A set of updates you should make to the domain name's DNS records to
let Hosting serve secure content on its behalf.`,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"desired": {
Type: schema.TypeList,
Optional: true,
Description: `The set of DNS records Hosting needs to serve secure content on the domain.`,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"domain_name": {
Type: schema.TypeString,
Optional: true,
Description: `The domain name the record set pertains to.`,
},
"records": {
Type: schema.TypeList,
Optional: true,
Description: `Records on the domain`,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"domain_name": {
Type: schema.TypeString,
Optional: true,
Description: `The domain name the record pertains to, e.g. 'foo.bar.com.'.`,
},
"rdata": {
Type: schema.TypeString,
Optional: true,
Description: `The data of the record. The meaning of the value depends on record type:
- A and AAAA: IP addresses for the domain name.
- CNAME: Another domain to check for records.
- TXT: Arbitrary text strings associated with the domain name. Hosting
uses TXT records to determine a which Firebase Projects have
permission to act on the domain name's behalf.
- CAA: The record's flags, tag, and value, e.g. '0 issue "pki.goog"'.`,
},
"required_action": {
Type: schema.TypeString,
Optional: true,
Description: `Indicates the a required action for this record.`,
},
"type": {
Type: schema.TypeString,
Optional: true,
Description: `The record's type, which determines what data the record contains.`,
},
},
},
},
},
},
},
"discovered": {
Type: schema.TypeList,
Optional: true,
Description: `The set of DNS records Hosting discovered when inspecting a domain`,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"domain_name": {
Type: schema.TypeString,
Optional: true,
Description: `The domain name the record set pertains to.`,
},
"records": {
Type: schema.TypeList,
Optional: true,
Description: `Records on the domain`,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"domain_name": {
Type: schema.TypeString,
Optional: true,
Description: `The domain name the record pertains to, e.g. 'foo.bar.com.'.`,
},
"rdata": {
Type: schema.TypeString,
Optional: true,
Description: `The data of the record. The meaning of the value depends on record type:
- A and AAAA: IP addresses for the domain name.
- CNAME: Another domain to check for records.
- TXT: Arbitrary text strings associated with the domain name. Hosting
uses TXT records to determine a which Firebase Projects have
permission to act on the domain name's behalf.
- CAA: The record's flags, tag, and value, e.g. '0 issue "pki.goog"'.`,
},
"required_action": {
Type: schema.TypeString,
Optional: true,
Description: `Indicates the a required action for this record.`,
},
"type": {
Type: schema.TypeString,
Optional: true,
Description: `The record's type, which determines what data the record contains.`,
},
},
},
},
},
},
},
"check_time": {
Type: schema.TypeString,
Computed: true,
Description: `The last time Hosting checked your CustomDomain's DNS records.`,
},
},
},
},
"update_time": {
Type: schema.TypeString,
Computed: true,
Description: `The last time the 'CustomDomain' was updated.`,
},
"wait_dns_verification": {
Type: schema.TypeBool,
Optional: true,
ForceNew: true,
Default: false,
Description: `If true, Terraform will wait for DNS records to be fully resolved on the 'CustomDomain'.
If false, Terraform will not wait for DNS records on the 'CustomDomain'. Any issues in
the 'CustomDomain' will be returned and stored in the Terraform state.`,
},
"project": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
},
},
UseJSONNumber: true,
}
}
func resourceFirebaseHostingCustomDomainCreate(d *schema.ResourceData, meta interface{}) error {
config := meta.(*transport_tpg.Config)
userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent)
if err != nil {
return err
}
obj := make(map[string]interface{})
etagProp, err := expandFirebaseHostingCustomDomainEtag(d.Get("etag"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("etag"); !tpgresource.IsEmptyValue(reflect.ValueOf(etagProp)) && (ok || !reflect.DeepEqual(v, etagProp)) {
obj["etag"] = etagProp
}
certPreferenceProp, err := expandFirebaseHostingCustomDomainCertPreference(d.Get("cert_preference"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("cert_preference"); !tpgresource.IsEmptyValue(reflect.ValueOf(certPreferenceProp)) && (ok || !reflect.DeepEqual(v, certPreferenceProp)) {
obj["certPreference"] = certPreferenceProp
}
redirectTargetProp, err := expandFirebaseHostingCustomDomainRedirectTarget(d.Get("redirect_target"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("redirect_target"); !tpgresource.IsEmptyValue(reflect.ValueOf(redirectTargetProp)) && (ok || !reflect.DeepEqual(v, redirectTargetProp)) {
obj["redirectTarget"] = redirectTargetProp
}
url, err := tpgresource.ReplaceVars(d, config, "{{FirebaseHostingBasePath}}projects/{{project}}/sites/{{site_id}}/customDomains?customDomainId={{custom_domain}}")
if err != nil {
return err
}
log.Printf("[DEBUG] Creating new CustomDomain: %#v", obj)
billingProject := ""
project, err := tpgresource.GetProject(d, config)
if err != nil {
return fmt.Errorf("Error fetching project for CustomDomain: %s", err)
}
billingProject = project
// err == nil indicates that the billing_project value was found
if bp, err := tpgresource.GetBillingProject(d, config); err == nil {
billingProject = bp
}
res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{
Config: config,
Method: "POST",
Project: billingProject,
RawURL: url,
UserAgent: userAgent,
Body: obj,
Timeout: d.Timeout(schema.TimeoutCreate),
})
if err != nil {
return fmt.Errorf("Error creating CustomDomain: %s", err)
}
// Store the ID now
id, err := tpgresource.ReplaceVars(d, config, "projects/{{project}}/sites/{{site_id}}/customDomains/{{custom_domain}}")
if err != nil {
return fmt.Errorf("Error constructing id: %s", err)
}
d.SetId(id)
if d.Get("wait_dns_verification") == true {
// Wait for the creation operation to complete before treating the resource
// as created
var opRes map[string]interface{}
err = FirebaseHostingOperationWaitTimeWithResponse(
config, res, &opRes, project, "Creating CustomDomain", userAgent,
d.Timeout(schema.TimeoutCreate))
if err != nil {
// The resource didn't actually create
d.SetId("")
return fmt.Errorf("Error waiting to create CustomDomain: %s", err)
}
}
log.Printf("[DEBUG] Finished creating CustomDomain %q: %#v", d.Id(), res)
return resourceFirebaseHostingCustomDomainRead(d, meta)
}
func resourceFirebaseHostingCustomDomainRead(d *schema.ResourceData, meta interface{}) error {
config := meta.(*transport_tpg.Config)
userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent)
if err != nil {
return err
}
url, err := tpgresource.ReplaceVars(d, config, "{{FirebaseHostingBasePath}}projects/{{project}}/sites/{{site_id}}/customDomains/{{custom_domain}}")
if err != nil {
return err
}
billingProject := ""
project, err := tpgresource.GetProject(d, config)
if err != nil {
return fmt.Errorf("Error fetching project for CustomDomain: %s", err)
}
billingProject = project
// err == nil indicates that the billing_project value was found
if bp, err := tpgresource.GetBillingProject(d, config); err == nil {
billingProject = bp
}
res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{
Config: config,
Method: "GET",
Project: billingProject,
RawURL: url,
UserAgent: userAgent,
})
if err != nil {
return transport_tpg.HandleNotFoundError(err, d, fmt.Sprintf("FirebaseHostingCustomDomain %q", d.Id()))
}
// Explicitly set virtual fields to default values if unset
if _, ok := d.GetOkExists("wait_dns_verification"); !ok {
if err := d.Set("wait_dns_verification", false); err != nil {
return fmt.Errorf("Error setting wait_dns_verification: %s", err)
}
}
if err := d.Set("project", project); err != nil {
return fmt.Errorf("Error reading CustomDomain: %s", err)
}
if err := d.Set("name", flattenFirebaseHostingCustomDomainName(res["name"], d, config)); err != nil {
return fmt.Errorf("Error reading CustomDomain: %s", err)
}
if err := d.Set("create_time", flattenFirebaseHostingCustomDomainCreateTime(res["createTime"], d, config)); err != nil {
return fmt.Errorf("Error reading CustomDomain: %s", err)
}
if err := d.Set("update_time", flattenFirebaseHostingCustomDomainUpdateTime(res["updateTime"], d, config)); err != nil {
return fmt.Errorf("Error reading CustomDomain: %s", err)
}
if err := d.Set("delete_time", flattenFirebaseHostingCustomDomainDeleteTime(res["deleteTime"], d, config)); err != nil {
return fmt.Errorf("Error reading CustomDomain: %s", err)
}
if err := d.Set("expire_time", flattenFirebaseHostingCustomDomainExpireTime(res["expireTime"], d, config)); err != nil {
return fmt.Errorf("Error reading CustomDomain: %s", err)
}
if err := d.Set("etag", flattenFirebaseHostingCustomDomainEtag(res["etag"], d, config)); err != nil {
return fmt.Errorf("Error reading CustomDomain: %s", err)
}
if err := d.Set("host_state", flattenFirebaseHostingCustomDomainHostState(res["hostState"], d, config)); err != nil {
return fmt.Errorf("Error reading CustomDomain: %s", err)
}
if err := d.Set("ownership_state", flattenFirebaseHostingCustomDomainOwnershipState(res["ownershipState"], d, config)); err != nil {
return fmt.Errorf("Error reading CustomDomain: %s", err)
}
if err := d.Set("cert_preference", flattenFirebaseHostingCustomDomainCertPreference(res["certPreference"], d, config)); err != nil {
return fmt.Errorf("Error reading CustomDomain: %s", err)
}
if err := d.Set("redirect_target", flattenFirebaseHostingCustomDomainRedirectTarget(res["redirectTarget"], d, config)); err != nil {
return fmt.Errorf("Error reading CustomDomain: %s", err)
}
if err := d.Set("required_dns_updates", flattenFirebaseHostingCustomDomainRequiredDnsUpdates(res["requiredDnsUpdates"], d, config)); err != nil {
return fmt.Errorf("Error reading CustomDomain: %s", err)
}
if err := d.Set("issues", flattenFirebaseHostingCustomDomainIssues(res["issues"], d, config)); err != nil {
return fmt.Errorf("Error reading CustomDomain: %s", err)
}
if err := d.Set("cert", flattenFirebaseHostingCustomDomainCert(res["cert"], d, config)); err != nil {
return fmt.Errorf("Error reading CustomDomain: %s", err)
}
if err := d.Set("reconciling", flattenFirebaseHostingCustomDomainReconciling(res["reconciling"], d, config)); err != nil {
return fmt.Errorf("Error reading CustomDomain: %s", err)
}
return nil
}
func resourceFirebaseHostingCustomDomainUpdate(d *schema.ResourceData, meta interface{}) error {
config := meta.(*transport_tpg.Config)
userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent)
if err != nil {
return err
}
billingProject := ""
project, err := tpgresource.GetProject(d, config)
if err != nil {
return fmt.Errorf("Error fetching project for CustomDomain: %s", err)
}
billingProject = project
obj := make(map[string]interface{})
etagProp, err := expandFirebaseHostingCustomDomainEtag(d.Get("etag"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("etag"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, etagProp)) {
obj["etag"] = etagProp
}
certPreferenceProp, err := expandFirebaseHostingCustomDomainCertPreference(d.Get("cert_preference"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("cert_preference"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, certPreferenceProp)) {
obj["certPreference"] = certPreferenceProp
}
redirectTargetProp, err := expandFirebaseHostingCustomDomainRedirectTarget(d.Get("redirect_target"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("redirect_target"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, redirectTargetProp)) {
obj["redirectTarget"] = redirectTargetProp
}
url, err := tpgresource.ReplaceVars(d, config, "{{FirebaseHostingBasePath}}projects/{{project}}/sites/{{site_id}}/customDomains/{{custom_domain}}")
if err != nil {
return err
}
log.Printf("[DEBUG] Updating CustomDomain %q: %#v", d.Id(), obj)
updateMask := []string{}
if d.HasChange("etag") {
updateMask = append(updateMask, "etag")
}
if d.HasChange("cert_preference") {
updateMask = append(updateMask, "certPreference")
}
if d.HasChange("redirect_target") {
updateMask = append(updateMask, "redirectTarget")
}
// updateMask is a URL parameter but not present in the schema, so ReplaceVars
// won't set it
url, err = transport_tpg.AddQueryParams(url, map[string]string{"updateMask": strings.Join(updateMask, ",")})
if err != nil {
return err
}
// err == nil indicates that the billing_project value was found
if bp, err := tpgresource.GetBillingProject(d, config); err == nil {
billingProject = bp
}
// if updateMask is empty we are not updating anything so skip the post
if len(updateMask) > 0 {
res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{
Config: config,
Method: "PATCH",
Project: billingProject,
RawURL: url,
UserAgent: userAgent,
Body: obj,
Timeout: d.Timeout(schema.TimeoutUpdate),
})
if err != nil {
return fmt.Errorf("Error updating CustomDomain %q: %s", d.Id(), err)
} else {
log.Printf("[DEBUG] Finished updating CustomDomain %q: %#v", d.Id(), res)
}
err = FirebaseHostingOperationWaitTime(
config, res, project, "Updating CustomDomain", userAgent,
d.Timeout(schema.TimeoutUpdate))
if err != nil {
return err
}
}
return resourceFirebaseHostingCustomDomainRead(d, meta)
}
func resourceFirebaseHostingCustomDomainDelete(d *schema.ResourceData, meta interface{}) error {
config := meta.(*transport_tpg.Config)
userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent)
if err != nil {
return err
}
billingProject := ""
project, err := tpgresource.GetProject(d, config)
if err != nil {
return fmt.Errorf("Error fetching project for CustomDomain: %s", err)
}
billingProject = project
url, err := tpgresource.ReplaceVars(d, config, "{{FirebaseHostingBasePath}}projects/{{project}}/sites/{{site_id}}/customDomains/{{custom_domain}}")
if err != nil {
return err
}
var obj map[string]interface{}
log.Printf("[DEBUG] Deleting CustomDomain %q", d.Id())
// err == nil indicates that the billing_project value was found
if bp, err := tpgresource.GetBillingProject(d, config); err == nil {
billingProject = bp
}
res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{
Config: config,
Method: "DELETE",
Project: billingProject,
RawURL: url,
UserAgent: userAgent,
Body: obj,
Timeout: d.Timeout(schema.TimeoutDelete),
})
if err != nil {
return transport_tpg.HandleNotFoundError(err, d, "CustomDomain")
}
err = FirebaseHostingOperationWaitTime(
config, res, project, "Deleting CustomDomain", userAgent,
d.Timeout(schema.TimeoutDelete))
if err != nil {
return err
}
log.Printf("[DEBUG] Finished deleting CustomDomain %q: %#v", d.Id(), res)
return nil
}
func resourceFirebaseHostingCustomDomainImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
config := meta.(*transport_tpg.Config)
if err := tpgresource.ParseImportId([]string{
"^projects/(?P<project>[^/]+)/sites/(?P<site_id>[^/]+)/customDomains/(?P<custom_domain>[^/]+)$",
"^sites/(?P<site_id>[^/]+)/customDomains/(?P<custom_domain>[^/]+)$",
"^(?P<project>[^/]+)/(?P<site_id>[^/]+)/(?P<custom_domain>[^/]+)$",
"^(?P<site_id>[^/]+)/(?P<custom_domain>[^/]+)$",
}, d, config); err != nil {
return nil, err
}
// Replace import id for the resource id
id, err := tpgresource.ReplaceVars(d, config, "projects/{{project}}/sites/{{site_id}}/customDomains/{{custom_domain}}")
if err != nil {
return nil, fmt.Errorf("Error constructing id: %s", err)
}
d.SetId(id)
// Explicitly set virtual fields to default values on import
if err := d.Set("wait_dns_verification", false); err != nil {
return nil, fmt.Errorf("Error setting wait_dns_verification: %s", err)
}
return []*schema.ResourceData{d}, nil
}
func flattenFirebaseHostingCustomDomainName(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}
func flattenFirebaseHostingCustomDomainCreateTime(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}
func flattenFirebaseHostingCustomDomainUpdateTime(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}
func flattenFirebaseHostingCustomDomainDeleteTime(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}
func flattenFirebaseHostingCustomDomainExpireTime(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}
func flattenFirebaseHostingCustomDomainEtag(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}
func flattenFirebaseHostingCustomDomainHostState(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}
func flattenFirebaseHostingCustomDomainOwnershipState(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}
func flattenFirebaseHostingCustomDomainCertPreference(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}
func flattenFirebaseHostingCustomDomainRedirectTarget(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}
func flattenFirebaseHostingCustomDomainRequiredDnsUpdates(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
if v == nil {
return nil
}
original := v.(map[string]interface{})
if len(original) == 0 {
return nil
}
transformed := make(map[string]interface{})
transformed["check_time"] =
flattenFirebaseHostingCustomDomainRequiredDnsUpdatesCheckTime(original["checkTime"], d, config)
transformed["discovered"] =
flattenFirebaseHostingCustomDomainRequiredDnsUpdatesDiscovered(original["discovered"], d, config)
transformed["desired"] =
flattenFirebaseHostingCustomDomainRequiredDnsUpdatesDesired(original["desired"], d, config)
return []interface{}{transformed}
}
func flattenFirebaseHostingCustomDomainRequiredDnsUpdatesCheckTime(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}
func flattenFirebaseHostingCustomDomainRequiredDnsUpdatesDiscovered(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) 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{}{
"domain_name": flattenFirebaseHostingCustomDomainRequiredDnsUpdatesDiscoveredDomainName(original["domainName"], d, config),
"records": flattenFirebaseHostingCustomDomainRequiredDnsUpdatesDiscoveredRecords(original["records"], d, config),
})
}
return transformed
}
func flattenFirebaseHostingCustomDomainRequiredDnsUpdatesDiscoveredDomainName(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}
func flattenFirebaseHostingCustomDomainRequiredDnsUpdatesDiscoveredRecords(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) 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{}{
"domain_name": flattenFirebaseHostingCustomDomainRequiredDnsUpdatesDiscoveredRecordsDomainName(original["domainName"], d, config),
"type": flattenFirebaseHostingCustomDomainRequiredDnsUpdatesDiscoveredRecordsType(original["type"], d, config),
"rdata": flattenFirebaseHostingCustomDomainRequiredDnsUpdatesDiscoveredRecordsRdata(original["rdata"], d, config),
"required_action": flattenFirebaseHostingCustomDomainRequiredDnsUpdatesDiscoveredRecordsRequiredAction(original["requiredAction"], d, config),
})
}
return transformed
}
func flattenFirebaseHostingCustomDomainRequiredDnsUpdatesDiscoveredRecordsDomainName(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}
func flattenFirebaseHostingCustomDomainRequiredDnsUpdatesDiscoveredRecordsType(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}
func flattenFirebaseHostingCustomDomainRequiredDnsUpdatesDiscoveredRecordsRdata(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}
func flattenFirebaseHostingCustomDomainRequiredDnsUpdatesDiscoveredRecordsRequiredAction(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}
func flattenFirebaseHostingCustomDomainRequiredDnsUpdatesDesired(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) 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{}{
"domain_name": flattenFirebaseHostingCustomDomainRequiredDnsUpdatesDesiredDomainName(original["domainName"], d, config),
"records": flattenFirebaseHostingCustomDomainRequiredDnsUpdatesDesiredRecords(original["records"], d, config),
})
}
return transformed
}
func flattenFirebaseHostingCustomDomainRequiredDnsUpdatesDesiredDomainName(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}
func flattenFirebaseHostingCustomDomainRequiredDnsUpdatesDesiredRecords(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) 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{}{
"domain_name": flattenFirebaseHostingCustomDomainRequiredDnsUpdatesDesiredRecordsDomainName(original["domainName"], d, config),
"type": flattenFirebaseHostingCustomDomainRequiredDnsUpdatesDesiredRecordsType(original["type"], d, config),
"rdata": flattenFirebaseHostingCustomDomainRequiredDnsUpdatesDesiredRecordsRdata(original["rdata"], d, config),
"required_action": flattenFirebaseHostingCustomDomainRequiredDnsUpdatesDesiredRecordsRequiredAction(original["requiredAction"], d, config),
})
}
return transformed
}
func flattenFirebaseHostingCustomDomainRequiredDnsUpdatesDesiredRecordsDomainName(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}
func flattenFirebaseHostingCustomDomainRequiredDnsUpdatesDesiredRecordsType(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}
func flattenFirebaseHostingCustomDomainRequiredDnsUpdatesDesiredRecordsRdata(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}
func flattenFirebaseHostingCustomDomainRequiredDnsUpdatesDesiredRecordsRequiredAction(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}
func flattenFirebaseHostingCustomDomainIssues(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) 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{}{
"code": flattenFirebaseHostingCustomDomainIssuesCode(original["code"], d, config),
"message": flattenFirebaseHostingCustomDomainIssuesMessage(original["message"], d, config),
"details": flattenFirebaseHostingCustomDomainIssuesDetails(original["details"], d, config),
})
}
return transformed
}
func flattenFirebaseHostingCustomDomainIssuesCode(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
// Handles the string fixed64 format
if strVal, ok := v.(string); ok {
if intVal, err := tpgresource.StringToFixed64(strVal); err == nil {
return intVal
}
}
// number values are represented as float64
if floatVal, ok := v.(float64); ok {
intVal := int(floatVal)
return intVal
}
return v // let terraform core handle it otherwise
}
func flattenFirebaseHostingCustomDomainIssuesMessage(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}
func flattenFirebaseHostingCustomDomainIssuesDetails(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
if v == nil {
return nil
}
b, err := json.Marshal(v)
if err != nil {
// TODO: return error once https://github.com/GoogleCloudPlatform/magic-modules/issues/3257 is fixed.
log.Printf("[ERROR] failed to marshal schema to JSON: %v", err)
}
return string(b)
}
func flattenFirebaseHostingCustomDomainCert(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
if v == nil {
return nil
}
original := v.(map[string]interface{})
if len(original) == 0 {
return nil
}
transformed := make(map[string]interface{})
transformed["type"] =
flattenFirebaseHostingCustomDomainCertType(original["type"], d, config)
transformed["state"] =
flattenFirebaseHostingCustomDomainCertState(original["state"], d, config)
transformed["verification"] =
flattenFirebaseHostingCustomDomainCertVerification(original["verification"], d, config)
return []interface{}{transformed}
}
func flattenFirebaseHostingCustomDomainCertType(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}
func flattenFirebaseHostingCustomDomainCertState(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}
func flattenFirebaseHostingCustomDomainCertVerification(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
if v == nil {
return nil
}
original := v.(map[string]interface{})
if len(original) == 0 {
return nil
}
transformed := make(map[string]interface{})
transformed["dns"] =
flattenFirebaseHostingCustomDomainCertVerificationDns(original["dns"], d, config)
transformed["http"] =
flattenFirebaseHostingCustomDomainCertVerificationHttp(original["http"], d, config)
return []interface{}{transformed}
}
func flattenFirebaseHostingCustomDomainCertVerificationDns(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
if v == nil {
return nil
}
original := v.(map[string]interface{})
if len(original) == 0 {
return nil
}
transformed := make(map[string]interface{})
transformed["check_time"] =
flattenFirebaseHostingCustomDomainCertVerificationDnsCheckTime(original["checkTime"], d, config)
transformed["discovered"] =
flattenFirebaseHostingCustomDomainCertVerificationDnsDiscovered(original["discovered"], d, config)
transformed["desired"] =
flattenFirebaseHostingCustomDomainCertVerificationDnsDesired(original["desired"], d, config)
return []interface{}{transformed}
}
func flattenFirebaseHostingCustomDomainCertVerificationDnsCheckTime(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}
func flattenFirebaseHostingCustomDomainCertVerificationDnsDiscovered(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) 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{}{
"domain_name": flattenFirebaseHostingCustomDomainCertVerificationDnsDiscoveredDomainName(original["domainName"], d, config),
"records": flattenFirebaseHostingCustomDomainCertVerificationDnsDiscoveredRecords(original["records"], d, config),
})
}
return transformed
}
func flattenFirebaseHostingCustomDomainCertVerificationDnsDiscoveredDomainName(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}
func flattenFirebaseHostingCustomDomainCertVerificationDnsDiscoveredRecords(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) 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{}{
"domain_name": flattenFirebaseHostingCustomDomainCertVerificationDnsDiscoveredRecordsDomainName(original["domainName"], d, config),
"type": flattenFirebaseHostingCustomDomainCertVerificationDnsDiscoveredRecordsType(original["type"], d, config),
"rdata": flattenFirebaseHostingCustomDomainCertVerificationDnsDiscoveredRecordsRdata(original["rdata"], d, config),
"required_action": flattenFirebaseHostingCustomDomainCertVerificationDnsDiscoveredRecordsRequiredAction(original["requiredAction"], d, config),
})
}
return transformed
}
func flattenFirebaseHostingCustomDomainCertVerificationDnsDiscoveredRecordsDomainName(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}
func flattenFirebaseHostingCustomDomainCertVerificationDnsDiscoveredRecordsType(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}
func flattenFirebaseHostingCustomDomainCertVerificationDnsDiscoveredRecordsRdata(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}
func flattenFirebaseHostingCustomDomainCertVerificationDnsDiscoveredRecordsRequiredAction(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}
func flattenFirebaseHostingCustomDomainCertVerificationDnsDesired(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) 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{}{
"domain_name": flattenFirebaseHostingCustomDomainCertVerificationDnsDesiredDomainName(original["domainName"], d, config),
"records": flattenFirebaseHostingCustomDomainCertVerificationDnsDesiredRecords(original["records"], d, config),
})
}
return transformed
}
func flattenFirebaseHostingCustomDomainCertVerificationDnsDesiredDomainName(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}
func flattenFirebaseHostingCustomDomainCertVerificationDnsDesiredRecords(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) 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{}{
"domain_name": flattenFirebaseHostingCustomDomainCertVerificationDnsDesiredRecordsDomainName(original["domainName"], d, config),
"type": flattenFirebaseHostingCustomDomainCertVerificationDnsDesiredRecordsType(original["type"], d, config),
"rdata": flattenFirebaseHostingCustomDomainCertVerificationDnsDesiredRecordsRdata(original["rdata"], d, config),
"required_action": flattenFirebaseHostingCustomDomainCertVerificationDnsDesiredRecordsRequiredAction(original["requiredAction"], d, config),
})
}
return transformed
}
func flattenFirebaseHostingCustomDomainCertVerificationDnsDesiredRecordsDomainName(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}
func flattenFirebaseHostingCustomDomainCertVerificationDnsDesiredRecordsType(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}
func flattenFirebaseHostingCustomDomainCertVerificationDnsDesiredRecordsRdata(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}
func flattenFirebaseHostingCustomDomainCertVerificationDnsDesiredRecordsRequiredAction(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}
func flattenFirebaseHostingCustomDomainCertVerificationHttp(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
if v == nil {
return nil
}
original := v.(map[string]interface{})
if len(original) == 0 {
return nil
}
transformed := make(map[string]interface{})
transformed["path"] =
flattenFirebaseHostingCustomDomainCertVerificationHttpPath(original["path"], d, config)
transformed["desired"] =
flattenFirebaseHostingCustomDomainCertVerificationHttpDesired(original["desired"], d, config)
transformed["discovered"] =
flattenFirebaseHostingCustomDomainCertVerificationHttpDiscovered(original["discovered"], d, config)
transformed["last_check_time"] =
flattenFirebaseHostingCustomDomainCertVerificationHttpLastCheckTime(original["lastCheckTime"], d, config)
return []interface{}{transformed}
}
func flattenFirebaseHostingCustomDomainCertVerificationHttpPath(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}
func flattenFirebaseHostingCustomDomainCertVerificationHttpDesired(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}
func flattenFirebaseHostingCustomDomainCertVerificationHttpDiscovered(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}
func flattenFirebaseHostingCustomDomainCertVerificationHttpLastCheckTime(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}
func flattenFirebaseHostingCustomDomainReconciling(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}
func expandFirebaseHostingCustomDomainEtag(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
return v, nil
}
func expandFirebaseHostingCustomDomainCertPreference(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
return v, nil
}
func expandFirebaseHostingCustomDomainRedirectTarget(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
return v, nil
}