func NewService(ctx context.Context) (*storage.Service, error) {
	httpClient, err := google.DefaultClient(ctx, storage.CloudPlatformScope)
	if err != nil {
		return nil, err
	}
	client, err := storage.New(httpClient)
	if err != nil {
		return nil, err
	}
	client.UserAgent = UserAgent
	return client, nil
}
NewService returns a new client
package gcs
import (
	"context"
	"golang.org/x/oauth2/google"
	"google.golang.org/api/storage/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"reflect"
	"sigs.k8s.io/controller-reconciler/pkg/reconciler"
	"sigs.k8s.io/controller-reconciler/pkg/reconciler/manager"
	"sigs.k8s.io/controller-reconciler/pkg/reconciler/manager/gcp"
	"strings"
)
const (
	Type      = "gcs"
	UserAgent = "kcc/controller-manager"
)
type RsrcManager struct {
	name    string
	service *storage.Service
}
func Getter(ctx context.Context) func() (string, manager.Manager, error) {
	return func() (string, manager.Manager, error) {
		rm := &RsrcManager{}
		service, err := NewService(ctx)
		if err != nil {
			return "", nil, err
		}
		rm.WithService(service).WithName(Type + "Mgr")
		return Type, rm, nil
	}
}
func NewRsrcManager(ctx context.Context, name string) (*RsrcManager, error) {
	rm := &RsrcManager{}
	service, err := NewService(ctx)
	if err != nil {
		return nil, err
	}
	rm.WithService(service).WithName(name)
	return rm, nil
}
func (rm *RsrcManager) WithName(v string) *RsrcManager {
	rm.name = v
	return rm
}
func (rm *RsrcManager) WithService(s *storage.Service) *RsrcManager {
	rm.service = s
	return rm
}
type Object struct {
	Bucket    *storage.Bucket
	ProjectID string
}
func (o *Object) SetLabels(labels map[string]string) {
	o.Bucket.Labels = gcp.CompliantLabelMap(labels)
}
func (o *Object) SetOwnerReferences(refs *metav1.OwnerReference) bool { return false }
func (o *Object) IsSameAs(a interface{}) bool {
	same := false
	e := a.(*Object)
	if e.Bucket.Name == o.Bucket.Name {
		same = true
	}
	return same
}
func (o *Object) GetName() string {
	return "gcs-bucket/" + o.ProjectID + "/" + o.Bucket.Location + "/" + o.Bucket.Name
}
type Observable struct {
	Labels map[string]string
	Obj *storage.Bucket
	ProjectID string
}
func (o *Object) AsReconcilerObject() *reconciler.Object {
	return &reconciler.Object{
		Obj:       o,
		Lifecycle: reconciler.LifecycleManaged,
		Type:      Type,
	}
}
func NewObservable(labels map[string]string) reconciler.Observable {
	return reconciler.Observable{
		Type: Type,
		Obj: Observable{
			Labels: labels,
		},
	}
}
func (rm *RsrcManager) ObservablesFromObjects(bag []reconciler.Object, labels map[string]string) []reconciler.Observable {
	var observables []reconciler.Observable
	for _, item := range bag {
		if item.Type != Type {
			continue
		}
		obj, ok := item.Obj.(*Object)
		if !ok {
			continue
		}
		observables = append(observables, reconciler.Observable{Type: Type, Obj: Observable{Obj: obj.Bucket, Labels: labels}})
	}
	return observables
}
func (rm *RsrcManager) SpecDiffers(expected, observed *reconciler.Object) bool {
	e := expected.Obj.(*Object).Bucket
	o := observed.Obj.(*Object).Bucket
	return !reflect.DeepEqual(e.Acl, o.Acl) ||
		!reflect.DeepEqual(e.Billing, o.Billing) ||
		!reflect.DeepEqual(e.Cors, o.Cors) ||
		!reflect.DeepEqual(e.DefaultEventBasedHold, o.DefaultEventBasedHold) ||
		!reflect.DeepEqual(e.Encryption, o.Encryption) ||
		!reflect.DeepEqual(e.Labels, o.Labels) ||
		!reflect.DeepEqual(e.Lifecycle, o.Lifecycle) ||
		!strings.EqualFold(e.Location, o.Location) ||
		!reflect.DeepEqual(e.Logging, o.Logging) ||
		!reflect.DeepEqual(e.Name, o.Name) ||
		!reflect.DeepEqual(e.Owner, o.Owner) ||
		!reflect.DeepEqual(e.StorageClass, o.StorageClass) ||
		!reflect.DeepEqual(e.Versioning, o.Versioning) ||
		!reflect.DeepEqual(e.Website, o.Website)
}
func (rm *RsrcManager) Observe(observables ...reconciler.Observable) ([]reconciler.Object, error) {
	var returnval []reconciler.Object
	for _, item := range observables {
		obs, ok := item.Obj.(Observable)
		if !ok {
			continue
		}
		bkt, err := rm.service.Buckets.Get(obs.Obj.Name).Do()
		if err != nil {
			if gcp.IsNotFound(err) {
				continue
			}
			return []reconciler.Object{}, err
		}
		obj := Object{Bucket: bkt, ProjectID: obs.ProjectID}
		returnval = append(returnval, *obj.AsReconcilerObject())
	}
	return returnval, nil
}
func (rm *RsrcManager) Update(item reconciler.Object) error {
	bkt := item.Obj.(*Object).Bucket
	_, err := rm.service.Buckets.Patch(bkt.Name, bkt).Do()
	return err
}
func (rm *RsrcManager) Create(item reconciler.Object) error {
	o := item.Obj.(*Object)
	_, err := rm.service.Buckets.Insert(o.ProjectID, o.Bucket).Do()
	return err
}
func (rm *RsrcManager) Delete(item reconciler.Object) error {
	bkt := item.Obj.(*Object).Bucket
	err := rm.service.Buckets.Delete(bkt.Name).Do()
	return err
}
func NewObject(name string) (*reconciler.Object, error) {
	project, err := gcp.GetProjectFromMetadata()
	if err != nil {
		return nil, err
	}
	obj := &Object{
		Bucket: &storage.Bucket{
			Name: name,
		},
		ProjectID: project,
	}
	return obj.AsReconcilerObject(), nil
}