From e760c859de88a6e79b6dffc653dbf75f1630d8e3 Mon Sep 17 00:00:00 2001 From: Cody Oss <6331106+codyoss@users.noreply.github.com> Date: Thu, 29 Oct 2020 14:18:02 -0600 Subject: [PATCH] feat(billing/budgets): start generating apiv1 (#3099) --- billing/budgets/apiv1/budget_client.go | 347 ++++++++++++++++++ .../apiv1/budget_client_example_test.go | 138 +++++++ billing/budgets/apiv1/doc.go | 109 ++++++ internal/.repo-metadata-full.json | 8 + internal/gapicgen/generator/config.go | 13 +- 5 files changed, 613 insertions(+), 2 deletions(-) create mode 100644 billing/budgets/apiv1/budget_client.go create mode 100644 billing/budgets/apiv1/budget_client_example_test.go create mode 100644 billing/budgets/apiv1/doc.go diff --git a/billing/budgets/apiv1/budget_client.go b/billing/budgets/apiv1/budget_client.go new file mode 100644 index 00000000000..dde2f76d36c --- /dev/null +++ b/billing/budgets/apiv1/budget_client.go @@ -0,0 +1,347 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go_gapic. DO NOT EDIT. + +package budgets + +import ( + "context" + "fmt" + "math" + "net/url" + "time" + + "github.com/golang/protobuf/proto" + gax "github.com/googleapis/gax-go/v2" + "google.golang.org/api/iterator" + "google.golang.org/api/option" + gtransport "google.golang.org/api/transport/grpc" + budgetspb "google.golang.org/genproto/googleapis/cloud/billing/budgets/v1" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/metadata" +) + +var newBudgetClientHook clientHook + +// BudgetCallOptions contains the retry settings for each method of BudgetClient. +type BudgetCallOptions struct { + CreateBudget []gax.CallOption + UpdateBudget []gax.CallOption + GetBudget []gax.CallOption + ListBudgets []gax.CallOption + DeleteBudget []gax.CallOption +} + +func defaultBudgetClientOptions() []option.ClientOption { + return []option.ClientOption{ + option.WithEndpoint("billingbudgets.googleapis.com:443"), + option.WithGRPCDialOption(grpc.WithDisableServiceConfig()), + option.WithScopes(DefaultAuthScopes()...), + option.WithGRPCDialOption(grpc.WithDefaultCallOptions( + grpc.MaxCallRecvMsgSize(math.MaxInt32))), + } +} + +func defaultBudgetCallOptions() *BudgetCallOptions { + return &BudgetCallOptions{ + CreateBudget: []gax.CallOption{}, + UpdateBudget: []gax.CallOption{ + gax.WithRetry(func() gax.Retryer { + return gax.OnCodes([]codes.Code{ + codes.DeadlineExceeded, + codes.Unavailable, + }, gax.Backoff{ + Initial: 100 * time.Millisecond, + Max: 60000 * time.Millisecond, + Multiplier: 1.30, + }) + }), + }, + GetBudget: []gax.CallOption{ + gax.WithRetry(func() gax.Retryer { + return gax.OnCodes([]codes.Code{ + codes.DeadlineExceeded, + codes.Unavailable, + }, gax.Backoff{ + Initial: 100 * time.Millisecond, + Max: 60000 * time.Millisecond, + Multiplier: 1.30, + }) + }), + }, + ListBudgets: []gax.CallOption{ + gax.WithRetry(func() gax.Retryer { + return gax.OnCodes([]codes.Code{ + codes.DeadlineExceeded, + codes.Unavailable, + }, gax.Backoff{ + Initial: 100 * time.Millisecond, + Max: 60000 * time.Millisecond, + Multiplier: 1.30, + }) + }), + }, + DeleteBudget: []gax.CallOption{ + gax.WithRetry(func() gax.Retryer { + return gax.OnCodes([]codes.Code{ + codes.DeadlineExceeded, + codes.Unavailable, + }, gax.Backoff{ + Initial: 100 * time.Millisecond, + Max: 60000 * time.Millisecond, + Multiplier: 1.30, + }) + }), + }, + } +} + +// BudgetClient is a client for interacting with Cloud Billing Budget API. +// +// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. +type BudgetClient struct { + // Connection pool of gRPC connections to the service. + connPool gtransport.ConnPool + + // The gRPC API client. + budgetClient budgetspb.BudgetServiceClient + + // The call options for this service. + CallOptions *BudgetCallOptions + + // The x-goog-* metadata to be sent with each request. + xGoogMetadata metadata.MD +} + +// NewBudgetClient creates a new budget service client. +// +// BudgetService stores Cloud Billing budgets, which define a +// budget plan and rules to execute as we track spend against that plan. +func NewBudgetClient(ctx context.Context, opts ...option.ClientOption) (*BudgetClient, error) { + clientOpts := defaultBudgetClientOptions() + + if newBudgetClientHook != nil { + hookOpts, err := newBudgetClientHook(ctx, clientHookParams{}) + if err != nil { + return nil, err + } + clientOpts = append(clientOpts, hookOpts...) + } + + connPool, err := gtransport.DialPool(ctx, append(clientOpts, opts...)...) + if err != nil { + return nil, err + } + c := &BudgetClient{ + connPool: connPool, + CallOptions: defaultBudgetCallOptions(), + + budgetClient: budgetspb.NewBudgetServiceClient(connPool), + } + c.setGoogleClientInfo() + + return c, nil +} + +// Connection returns a connection to the API service. +// +// Deprecated. +func (c *BudgetClient) Connection() *grpc.ClientConn { + return c.connPool.Conn() +} + +// Close closes the connection to the API service. The user should invoke this when +// the client is no longer required. +func (c *BudgetClient) Close() error { + return c.connPool.Close() +} + +// setGoogleClientInfo sets the name and version of the application in +// the `x-goog-api-client` header passed on each request. Intended for +// use by Google-written clients. +func (c *BudgetClient) setGoogleClientInfo(keyval ...string) { + kv := append([]string{"gl-go", versionGo()}, keyval...) + kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) + c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) +} + +// CreateBudget creates a new budget. See +// Quotas and limits (at https://cloud.google.com/billing/quotas) +// for more information on the limits of the number of budgets you can create. +func (c *BudgetClient) CreateBudget(ctx context.Context, req *budgetspb.CreateBudgetRequest, opts ...gax.CallOption) (*budgetspb.Budget, error) { + md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) + ctx = insertMetadata(ctx, c.xGoogMetadata, md) + opts = append(c.CallOptions.CreateBudget[0:len(c.CallOptions.CreateBudget):len(c.CallOptions.CreateBudget)], opts...) + var resp *budgetspb.Budget + err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { + var err error + resp, err = c.budgetClient.CreateBudget(ctx, req, settings.GRPC...) + return err + }, opts...) + if err != nil { + return nil, err + } + return resp, nil +} + +// UpdateBudget updates a budget and returns the updated budget. +// +// WARNING: There are some fields exposed on the Google Cloud Console that +// aren’t available on this API. Budget fields that are not exposed in +// this API will not be changed by this method. +func (c *BudgetClient) UpdateBudget(ctx context.Context, req *budgetspb.UpdateBudgetRequest, opts ...gax.CallOption) (*budgetspb.Budget, error) { + md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "budget.name", url.QueryEscape(req.GetBudget().GetName()))) + ctx = insertMetadata(ctx, c.xGoogMetadata, md) + opts = append(c.CallOptions.UpdateBudget[0:len(c.CallOptions.UpdateBudget):len(c.CallOptions.UpdateBudget)], opts...) + var resp *budgetspb.Budget + err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { + var err error + resp, err = c.budgetClient.UpdateBudget(ctx, req, settings.GRPC...) + return err + }, opts...) + if err != nil { + return nil, err + } + return resp, nil +} + +// GetBudget returns a budget. +// +// WARNING: There are some fields exposed on the Google Cloud Console that +// aren’t available on this API. When reading from the API, you will not +// see these fields in the return value, though they may have been set +// in the Cloud Console. +func (c *BudgetClient) GetBudget(ctx context.Context, req *budgetspb.GetBudgetRequest, opts ...gax.CallOption) (*budgetspb.Budget, error) { + md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) + ctx = insertMetadata(ctx, c.xGoogMetadata, md) + opts = append(c.CallOptions.GetBudget[0:len(c.CallOptions.GetBudget):len(c.CallOptions.GetBudget)], opts...) + var resp *budgetspb.Budget + err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { + var err error + resp, err = c.budgetClient.GetBudget(ctx, req, settings.GRPC...) + return err + }, opts...) + if err != nil { + return nil, err + } + return resp, nil +} + +// ListBudgets returns a list of budgets for a billing account. +// +// WARNING: There are some fields exposed on the Google Cloud Console that +// aren’t available on this API. When reading from the API, you will not +// see these fields in the return value, though they may have been set +// in the Cloud Console. +func (c *BudgetClient) ListBudgets(ctx context.Context, req *budgetspb.ListBudgetsRequest, opts ...gax.CallOption) *BudgetIterator { + md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) + ctx = insertMetadata(ctx, c.xGoogMetadata, md) + opts = append(c.CallOptions.ListBudgets[0:len(c.CallOptions.ListBudgets):len(c.CallOptions.ListBudgets)], opts...) + it := &BudgetIterator{} + req = proto.Clone(req).(*budgetspb.ListBudgetsRequest) + it.InternalFetch = func(pageSize int, pageToken string) ([]*budgetspb.Budget, string, error) { + var resp *budgetspb.ListBudgetsResponse + req.PageToken = pageToken + if pageSize > math.MaxInt32 { + req.PageSize = math.MaxInt32 + } else { + req.PageSize = int32(pageSize) + } + err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { + var err error + resp, err = c.budgetClient.ListBudgets(ctx, req, settings.GRPC...) + return err + }, opts...) + if err != nil { + return nil, "", err + } + + it.Response = resp + return resp.Budgets, resp.NextPageToken, nil + } + fetch := func(pageSize int, pageToken string) (string, error) { + items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) + if err != nil { + return "", err + } + it.items = append(it.items, items...) + return nextPageToken, nil + } + it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) + it.pageInfo.MaxSize = int(req.PageSize) + it.pageInfo.Token = req.PageToken + return it +} + +// DeleteBudget deletes a budget. Returns successfully if already deleted. +func (c *BudgetClient) DeleteBudget(ctx context.Context, req *budgetspb.DeleteBudgetRequest, opts ...gax.CallOption) error { + md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) + ctx = insertMetadata(ctx, c.xGoogMetadata, md) + opts = append(c.CallOptions.DeleteBudget[0:len(c.CallOptions.DeleteBudget):len(c.CallOptions.DeleteBudget)], opts...) + err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { + var err error + _, err = c.budgetClient.DeleteBudget(ctx, req, settings.GRPC...) + return err + }, opts...) + return err +} + +// BudgetIterator manages a stream of *budgetspb.Budget. +type BudgetIterator struct { + items []*budgetspb.Budget + pageInfo *iterator.PageInfo + nextFunc func() error + + // Response is the raw response for the current page. + // It must be cast to the RPC response type. + // Calling Next() or InternalFetch() updates this value. + Response interface{} + + // InternalFetch is for use by the Google Cloud Libraries only. + // It is not part of the stable interface of this package. + // + // InternalFetch returns results from a single call to the underlying RPC. + // The number of results is no greater than pageSize. + // If there are no more results, nextPageToken is empty and err is nil. + InternalFetch func(pageSize int, pageToken string) (results []*budgetspb.Budget, nextPageToken string, err error) +} + +// PageInfo supports pagination. See the google.golang.org/api/iterator package for details. +func (it *BudgetIterator) PageInfo() *iterator.PageInfo { + return it.pageInfo +} + +// Next returns the next result. Its second return value is iterator.Done if there are no more +// results. Once Next returns Done, all subsequent calls will return Done. +func (it *BudgetIterator) Next() (*budgetspb.Budget, error) { + var item *budgetspb.Budget + if err := it.nextFunc(); err != nil { + return item, err + } + item = it.items[0] + it.items = it.items[1:] + return item, nil +} + +func (it *BudgetIterator) bufLen() int { + return len(it.items) +} + +func (it *BudgetIterator) takeBuf() interface{} { + b := it.items + it.items = nil + return b +} diff --git a/billing/budgets/apiv1/budget_client_example_test.go b/billing/budgets/apiv1/budget_client_example_test.go new file mode 100644 index 00000000000..1469bcca549 --- /dev/null +++ b/billing/budgets/apiv1/budget_client_example_test.go @@ -0,0 +1,138 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go_gapic. DO NOT EDIT. + +package budgets_test + +import ( + "context" + + budgets "cloud.google.com/go/billing/budgets/apiv1" + "google.golang.org/api/iterator" + budgetspb "google.golang.org/genproto/googleapis/cloud/billing/budgets/v1" +) + +func ExampleNewBudgetClient() { + ctx := context.Background() + c, err := budgets.NewBudgetClient(ctx) + if err != nil { + // TODO: Handle error. + } + // TODO: Use client. + _ = c +} + +func ExampleBudgetClient_CreateBudget() { + // import budgetspb "google.golang.org/genproto/googleapis/cloud/billing/budgets/v1" + + ctx := context.Background() + c, err := budgets.NewBudgetClient(ctx) + if err != nil { + // TODO: Handle error. + } + + req := &budgetspb.CreateBudgetRequest{ + // TODO: Fill request struct fields. + } + resp, err := c.CreateBudget(ctx, req) + if err != nil { + // TODO: Handle error. + } + // TODO: Use resp. + _ = resp +} + +func ExampleBudgetClient_UpdateBudget() { + // import budgetspb "google.golang.org/genproto/googleapis/cloud/billing/budgets/v1" + + ctx := context.Background() + c, err := budgets.NewBudgetClient(ctx) + if err != nil { + // TODO: Handle error. + } + + req := &budgetspb.UpdateBudgetRequest{ + // TODO: Fill request struct fields. + } + resp, err := c.UpdateBudget(ctx, req) + if err != nil { + // TODO: Handle error. + } + // TODO: Use resp. + _ = resp +} + +func ExampleBudgetClient_GetBudget() { + // import budgetspb "google.golang.org/genproto/googleapis/cloud/billing/budgets/v1" + + ctx := context.Background() + c, err := budgets.NewBudgetClient(ctx) + if err != nil { + // TODO: Handle error. + } + + req := &budgetspb.GetBudgetRequest{ + // TODO: Fill request struct fields. + } + resp, err := c.GetBudget(ctx, req) + if err != nil { + // TODO: Handle error. + } + // TODO: Use resp. + _ = resp +} + +func ExampleBudgetClient_ListBudgets() { + // import budgetspb "google.golang.org/genproto/googleapis/cloud/billing/budgets/v1" + // import "google.golang.org/api/iterator" + + ctx := context.Background() + c, err := budgets.NewBudgetClient(ctx) + if err != nil { + // TODO: Handle error. + } + + req := &budgetspb.ListBudgetsRequest{ + // TODO: Fill request struct fields. + } + it := c.ListBudgets(ctx, req) + for { + resp, err := it.Next() + if err == iterator.Done { + break + } + if err != nil { + // TODO: Handle error. + } + // TODO: Use resp. + _ = resp + } +} + +func ExampleBudgetClient_DeleteBudget() { + ctx := context.Background() + c, err := budgets.NewBudgetClient(ctx) + if err != nil { + // TODO: Handle error. + } + + req := &budgetspb.DeleteBudgetRequest{ + // TODO: Fill request struct fields. + } + err = c.DeleteBudget(ctx, req) + if err != nil { + // TODO: Handle error. + } +} diff --git a/billing/budgets/apiv1/doc.go b/billing/budgets/apiv1/doc.go new file mode 100644 index 00000000000..161df9aad30 --- /dev/null +++ b/billing/budgets/apiv1/doc.go @@ -0,0 +1,109 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go_gapic. DO NOT EDIT. + +// Package budgets is an auto-generated package for the +// Cloud Billing Budget API. +// +// The Cloud Billing Budget API stores Cloud Billing budgets, which define a +// budget plan and the rules to execute as spend is tracked against that +// plan. +// +// NOTE: This package is in beta. It is not stable, and may be subject to changes. +// +// Use of Context +// +// The ctx passed to NewClient is used for authentication requests and +// for creating the underlying connection, but is not used for subsequent calls. +// Individual methods on the client use the ctx given to them. +// +// To close the open connection, use the Close() method. +// +// For information about setting deadlines, reusing contexts, and more +// please visit godoc.org/cloud.google.com/go. +package budgets // import "cloud.google.com/go/billing/budgets/apiv1" + +import ( + "context" + "runtime" + "strings" + "unicode" + + "google.golang.org/api/option" + "google.golang.org/grpc/metadata" +) + +// For more information on implementing a client constructor hook, see +// https://github.com/googleapis/google-cloud-go/wiki/Customizing-constructors. +type clientHookParams struct{} +type clientHook func(context.Context, clientHookParams) ([]option.ClientOption, error) + +const versionClient = "20201027" + +func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { + out, _ := metadata.FromOutgoingContext(ctx) + out = out.Copy() + for _, md := range mds { + for k, v := range md { + out[k] = append(out[k], v...) + } + } + return metadata.NewOutgoingContext(ctx, out) +} + +// DefaultAuthScopes reports the default set of authentication scopes to use with this package. +func DefaultAuthScopes() []string { + return []string{ + "https://www.googleapis.com/auth/cloud-billing", + "https://www.googleapis.com/auth/cloud-platform", + } +} + +// versionGo returns the Go runtime version. The returned string +// has no whitespace, suitable for reporting in header. +func versionGo() string { + const develPrefix = "devel +" + + s := runtime.Version() + if strings.HasPrefix(s, develPrefix) { + s = s[len(develPrefix):] + if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { + s = s[:p] + } + return s + } + + notSemverRune := func(r rune) bool { + return !strings.ContainsRune("0123456789.", r) + } + + if strings.HasPrefix(s, "go1") { + s = s[2:] + var prerelease string + if p := strings.IndexFunc(s, notSemverRune); p >= 0 { + s, prerelease = s[:p], s[p:] + } + if strings.HasSuffix(s, ".") { + s += "0" + } else if strings.Count(s, ".") < 2 { + s += ".0" + } + if prerelease != "" { + s += "-" + prerelease + } + return s + } + return "UNKNOWN" +} diff --git a/internal/.repo-metadata-full.json b/internal/.repo-metadata-full.json index 7e576edc271..b39a53da9ab 100644 --- a/internal/.repo-metadata-full.json +++ b/internal/.repo-metadata-full.json @@ -183,6 +183,14 @@ "docs_url": "https://pkg.go.dev/cloud.google.com/go/billing/apiv1", "release_level": "ga" }, + "cloud.google.com/go/billing/budgets/apiv1": { + "distribution_name": "cloud.google.com/go/billing/budgets/apiv1", + "description": "Cloud Billing Budget API", + "language": "Go", + "client_library_type": "generated", + "docs_url": "https://pkg.go.dev/cloud.google.com/go/billing/budgets/apiv1", + "release_level": "beta" + }, "cloud.google.com/go/billing/budgets/apiv1beta1": { "distribution_name": "cloud.google.com/go/billing/budgets/apiv1beta1", "description": "", diff --git a/internal/gapicgen/generator/config.go b/internal/gapicgen/generator/config.go index ad3d90b251f..a4871621eba 100644 --- a/internal/gapicgen/generator/config.go +++ b/internal/gapicgen/generator/config.go @@ -776,6 +776,15 @@ var microgenGapicConfigs = []*microgenConfig{ apiServiceConfigPath: "google/cloud/notebooks/v1beta1/notebooks_v1beta1.yaml", releaseLevel: "beta", }, + { + inputDirectoryPath: "google/cloud/billing/budgets/v1", + pkg: "budgets", + importPath: "cloud.google.com/go/billing/budgets/apiv1", + gRPCServiceConfigPath: "google/cloud/billing/budgets/v1/billingbudgets_grpc_service_config.json", + apiServiceConfigPath: "google/cloud/billing/budgets/v1/billingbudgets.yaml", + // GA after 2020/11/27 + releaseLevel: "beta", + }, { inputDirectoryPath: "google/cloud/billing/budgets/v1beta1", pkg: "budgets", @@ -839,7 +848,7 @@ var microgenGapicConfigs = []*microgenConfig{ importPath: "cloud.google.com/go/websecurityscanner/apiv1", gRPCServiceConfigPath: "google/cloud/websecurityscanner/v1/websecurityscanner_grpc_service_config.json", apiServiceConfigPath: "google/cloud/websecurityscanner/v1/websecurityscanner_v1.yaml", - // GA after 2020/13/12 + // GA after 2020/11/13 releaseLevel: "beta", }, { @@ -848,7 +857,7 @@ var microgenGapicConfigs = []*microgenConfig{ importPath: "cloud.google.com/go/managedidentities/apiv1", gRPCServiceConfigPath: "google/cloud/managedidentities/v1/managedidentities_grpc_service_config.json", apiServiceConfigPath: "google/cloud/managedidentities/v1/managedidentities_v1.yaml", - // GA after 2020/15/12 + // GA after 2020/11/15 releaseLevel: "beta", },