<commit_before>package google

import (
	"context"
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"runtime"
	"strings"

	"github.com/hashicorp/terraform/helper/logging"
	"github.com/hashicorp/terraform/helper/pathorcontents"
	"github.com/hashicorp/terraform/terraform"

	"golang.org/x/oauth2"
	"golang.org/x/oauth2/google"
	"golang.org/x/oauth2/jwt"
	"google.golang.org/api/bigquery/v2"
	"google.golang.org/api/cloudbilling/v1"
	"google.golang.org/api/cloudfunctions/v1"
	"google.golang.org/api/cloudiot/v1"
	"google.golang.org/api/cloudkms/v1"
	"google.golang.org/api/cloudresourcemanager/v1"
	resourceManagerV2Beta1 "google.golang.org/api/cloudresourcemanager/v2beta1"
	computeBeta "google.golang.org/api/compute/v0.beta"
	"google.golang.org/api/compute/v1"
	"google.golang.org/api/container/v1"
	containerBeta "google.golang.org/api/container/v1beta1"
	"google.golang.org/api/dataflow/v1b3"
	"google.golang.org/api/dataproc/v1"
	"google.golang.org/api/dns/v1"
	"google.golang.org/api/iam/v1"
	cloudlogging "google.golang.org/api/logging/v2"
	"google.golang.org/api/pubsub/v1"
	"google.golang.org/api/runtimeconfig/v1beta1"
	"google.golang.org/api/servicemanagement/v1"
	"google.golang.org/api/sourcerepo/v1"
	"google.golang.org/api/spanner/v1"
	"google.golang.org/api/sqladmin/v1beta4"
	"google.golang.org/api/storage/v1"
)

// Config is the configuration structure used to instantiate the Google
// provider.
type Config struct {
	Credentials string
	Project     string
	Region      string
	Zone        string

	client    *http.Client
	userAgent string

	tokenSource oauth2.TokenSource

	clientBilling                *cloudbilling.Service
	clientCompute                *compute.Service
	clientComputeBeta            *computeBeta.Service
	clientContainer              *container.Service
	clientContainerBeta          *containerBeta.Service
	clientDataproc               *dataproc.Service
	clientDataflow               *dataflow.Service
	clientDns                    *dns.Service
	clientKms                    *cloudkms.Service
	clientLogging                *cloudlogging.Service
	clientPubsub                 *pubsub.Service
	clientResourceManager        *cloudresourcemanager.Service
	clientResourceManagerV2Beta1 *resourceManagerV2Beta1.Service
	clientRuntimeconfig          *runtimeconfig.Service
	clientSpanner                *spanner.Service
	clientSourceRepo             *sourcerepo.Service
	clientStorage                *storage.Service
	clientSqlAdmin               *sqladmin.Service
	clientIAM                    *iam.Service
	clientServiceMan             *servicemanagement.APIService
	clientBigQuery               *bigquery.Service
	clientCloudFunctions         *cloudfunctions.Service
	clientCloudIoT               *cloudiot.Service

	bigtableClientFactory *BigtableClientFactory
}

func (c *Config) loadAndValidate() error {
	var account accountFile
	clientScopes := []string{
		"https://www.googleapis.com/auth/compute",
		"https://www.googleapis.com/auth/cloud-platform",
		"https://www.googleapis.com/auth/ndev.clouddns.readwrite",
		"https://www.googleapis.com/auth/devstorage.full_control",
	}

	var client *http.Client
	var tokenSource oauth2.TokenSource

	if c.Credentials != "" {
		contents, _, err := pathorcontents.Read(c.Credentials)
		if err != nil {
			return fmt.Errorf("Error loading credentials: %s", err)
		}

		// Assume account_file is a JSON string
		if err := parseJSON(&account, contents); err != nil {
			return fmt.Errorf("Error parsing credentials '%s': %s", contents, err)
		}

		// Get the token for use in our requests
		log.Printf("[INFO] Requesting Google token...")
		log.Printf("[INFO]   -- Email: %s", account.ClientEmail)
		log.Printf("[INFO]   -- Scopes: %s", clientScopes)
		log.Printf("[INFO]   -- Private Key Length: %d", len(account.PrivateKey))

		conf := jwt.Config{
			Email:      account.ClientEmail,
			PrivateKey: []byte(account.PrivateKey),
			Scopes:     clientScopes,
			TokenURL:   "https://accounts.google.com/o/oauth2/token",
		}

		// Initiate an http.Client. The following GET request will be
		// authorized and authenticated on the behalf of
		// your service account.
		client = conf.Client(context.Background())

		tokenSource = conf.TokenSource(context.Background())
	} else {
		log.Printf("[INFO] Authenticating using DefaultClient")
		err := error(nil)
		client, err = google.DefaultClient(context.Background(), clientScopes...)
		if err != nil {
			return err
		}

		tokenSource, err = google.DefaultTokenSource(context.Background(), clientScopes...)
		if err != nil {
			return err
		}
	}

	c.tokenSource = tokenSource

	client.Transport = logging.NewTransport("Google", client.Transport)

	versionString := terraform.VersionString()
	userAgent := fmt.Sprintf(
		"(%s %s) Terraform/%s", runtime.GOOS, runtime.GOARCH, versionString)
<commit_msg>Use standard user-agent header (#1332)<commit_after>package google

import (
	"context"
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"strings"

	"github.com/hashicorp/terraform/helper/logging"
	"github.com/hashicorp/terraform/helper/pathorcontents"
	"github.com/hashicorp/terraform/version"

	"golang.org/x/oauth2"
	"golang.org/x/oauth2/google"
	"golang.org/x/oauth2/jwt"
	"google.golang.org/api/bigquery/v2"
	"google.golang.org/api/cloudbilling/v1"
	"google.golang.org/api/cloudfunctions/v1"
	"google.golang.org/api/cloudiot/v1"
	"google.golang.org/api/cloudkms/v1"
	"google.golang.org/api/cloudresourcemanager/v1"
	resourceManagerV2Beta1 "google.golang.org/api/cloudresourcemanager/v2beta1"
	computeBeta "google.golang.org/api/compute/v0.beta"
	"google.golang.org/api/compute/v1"
	"google.golang.org/api/container/v1"
	containerBeta "google.golang.org/api/container/v1beta1"
	"google.golang.org/api/dataflow/v1b3"
	"google.golang.org/api/dataproc/v1"
	"google.golang.org/api/dns/v1"
	"google.golang.org/api/iam/v1"
	cloudlogging "google.golang.org/api/logging/v2"
	"google.golang.org/api/pubsub/v1"
	"google.golang.org/api/runtimeconfig/v1beta1"
	"google.golang.org/api/servicemanagement/v1"
	"google.golang.org/api/sourcerepo/v1"
	"google.golang.org/api/spanner/v1"
	"google.golang.org/api/sqladmin/v1beta4"
	"google.golang.org/api/storage/v1"
)

// Config is the configuration structure used to instantiate the Google
// provider.
type Config struct {
	Credentials string
	Project     string
	Region      string
	Zone        string

	client    *http.Client
	userAgent string

	tokenSource oauth2.TokenSource

	clientBilling                *cloudbilling.Service
	clientCompute                *compute.Service
	clientComputeBeta            *computeBeta.Service
	clientContainer              *container.Service
	clientContainerBeta          *containerBeta.Service
	clientDataproc               *dataproc.Service
	clientDataflow               *dataflow.Service
	clientDns                    *dns.Service
	clientKms                    *cloudkms.Service
	clientLogging                *cloudlogging.Service
	clientPubsub                 *pubsub.Service
	clientResourceManager        *cloudresourcemanager.Service
	clientResourceManagerV2Beta1 *resourceManagerV2Beta1.Service
	clientRuntimeconfig          *runtimeconfig.Service
	clientSpanner                *spanner.Service
	clientSourceRepo             *sourcerepo.Service
	clientStorage                *storage.Service
	clientSqlAdmin               *sqladmin.Service
	clientIAM                    *iam.Service
	clientServiceMan             *servicemanagement.APIService
	clientBigQuery               *bigquery.Service
	clientCloudFunctions         *cloudfunctions.Service
	clientCloudIoT               *cloudiot.Service

	bigtableClientFactory *BigtableClientFactory
}

func (c *Config) loadAndValidate() error {
	var account accountFile
	clientScopes := []string{
		"https://www.googleapis.com/auth/compute",
		"https://www.googleapis.com/auth/cloud-platform",
		"https://www.googleapis.com/auth/ndev.clouddns.readwrite",
		"https://www.googleapis.com/auth/devstorage.full_control",
	}

	var client *http.Client
	var tokenSource oauth2.TokenSource

	if c.Credentials != "" {
		contents, _, err := pathorcontents.Read(c.Credentials)
		if err != nil {
			return fmt.Errorf("Error loading credentials: %s", err)
		}

		// Assume account_file is a JSON string
		if err := parseJSON(&account, contents); err != nil {
			return fmt.Errorf("Error parsing credentials '%s': %s", contents, err)
		}

		// Get the token for use in our requests
		log.Printf("[INFO] Requesting Google token...")
		log.Printf("[INFO]   -- Email: %s", account.ClientEmail)
		log.Printf("[INFO]   -- Scopes: %s", clientScopes)
		log.Printf("[INFO]   -- Private Key Length: %d", len(account.PrivateKey))

		conf := jwt.Config{
			Email:      account.ClientEmail,
			PrivateKey: []byte(account.PrivateKey),
			Scopes:     clientScopes,
			TokenURL:   "https://accounts.google.com/o/oauth2/token",
		}

		// Initiate an http.Client. The following GET request will be
		// authorized and authenticated on the behalf of
		// your service account.
		client = conf.Client(context.Background())

		tokenSource = conf.TokenSource(context.Background())
	} else {
		log.Printf("[INFO] Authenticating using DefaultClient")
		err := error(nil)
		client, err = google.DefaultClient(context.Background(), clientScopes...)
		if err != nil {
			return err
		}

		tokenSource, err = google.DefaultTokenSource(context.Background(), clientScopes...)
		if err != nil {
			return err
		}
	}

	c.tokenSource = tokenSource

	client.Transport = logging.NewTransport("Google", client.Transport)

	projectURL := "https://www.terraform.io"
	userAgent := fmt.Sprintf("Terraform/%s (+%s)",
		version.String(), projectURL)

{'fraction_non_alphanumeric': 0.11921079958463136, 'fraction_numerical': 0.008722741433021807, 'mean_word_length': 3.3285393258426965, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 11, 'lorem ipsum': 0, 'www.': 9, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4464137', 'n_tokens_mistral': 3354, 'n_tokens_neox': 3116, 'n_words': 544}