// Copyright 2020 Google LLC.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Code generated file. DO NOT EDIT.

// Package securitycenter provides access to the Security Command Center API.
//
// For product documentation, see: https://console.cloud.google.com/apis/api/securitycenter.googleapis.com/overview
//
// Creating a client
//
// Usage example:
//
//   import "google.golang.org/api/securitycenter/v1p1alpha1"
//   ...
//   ctx := context.Background()
//   securitycenterService, err := securitycenter.NewService(ctx)
//
// In this example, Google Application Default Credentials are used for authentication.
//
// For information on how to create and obtain Application Default Credentials, see https://developers.google.com/identity/protocols/application-default-credentials.
//
// Other authentication options
//
// To use an API key for authentication (note: some APIs do not support API keys), use option.WithAPIKey:
//
//   securitycenterService, err := securitycenter.NewService(ctx, option.WithAPIKey("AIza..."))
//
// To use an OAuth token (e.g., a user token obtained via a three-legged OAuth flow), use option.WithTokenSource:
//
//   config := &oauth2.Config{...}
//   // ...
//   token, err := config.Exchange(ctx, ...)
//   securitycenterService, err := securitycenter.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See https://godoc.org/google.golang.org/api/option/ for details on options.
package securitycenter // import "google.golang.org/api/securitycenter/v1p1alpha1"

import (
	"bytes"
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"strconv"
	"strings"

	googleapi "google.golang.org/api/googleapi"
	gensupport "google.golang.org/api/internal/gensupport"
	option "google.golang.org/api/option"
	internaloption "google.golang.org/api/option/internaloption"
	htransport "google.golang.org/api/transport/http"
)

// Always reference these packages, just in case the auto-generated code
// below doesn't.
var _ = bytes.NewBuffer
var _ = strconv.Itoa
var _ = fmt.Sprintf
var _ = json.NewDecoder
var _ = io.Copy
var _ = url.Parse
var _ = gensupport.MarshalJSON
var _ = googleapi.Version
var _ = errors.New
var _ = strings.Replace
var _ = context.Canceled
var _ = internaloption.WithDefaultEndpoint

const apiId = "securitycenter:v1p1alpha1"
const apiName = "securitycenter"
const apiVersion = "v1p1alpha1"
const basePath = "https://securitycenter.googleapis.com/"

// OAuth2 scopes used by this API.
const (
	// View and manage your data across Google Cloud Platform services
	CloudPlatformScope = "https://www.googleapis.com/auth/cloud-platform"
)

// NewService creates a new Service.
func NewService(ctx context.Context, opts ...option.ClientOption) (*Service, error) {
	scopesOption := option.WithScopes(
		"https://www.googleapis.com/auth/cloud-platform",
	)
	// NOTE: prepend, so we don't override user-specified scopes.
	opts = append([]option.ClientOption{scopesOption}, opts...)
	opts = append(opts, internaloption.WithDefaultEndpoint(basePath))
	client, endpoint, err := htransport.NewClient(ctx, opts...)
	if err != nil {
		return nil, err
	}
	s, err := New(client)
	if err != nil {
		return nil, err
	}
	if endpoint != "" {
		s.BasePath = endpoint
	}
	return s, nil
}

// New creates a new Service. It uses the provided http.Client for requests.
//
// Deprecated: please use NewService instead.
// To provide a custom HTTP client, use option.WithHTTPClient.
// If you are using google.golang.org/api/googleapis/transport.APIKey, use option.WithAPIKey with NewService instead.
func New(client *http.Client) (*Service, error) {
	if client == nil {
		return nil, errors.New("client is nil")
	}
	s := &Service{client: client, BasePath: basePath}
	s.Organizations = NewOrganizationsService(s)
	return s, nil
}

type Service struct {
	client    *http.Client
	BasePath  string // API endpoint base URL
	UserAgent string // optional additional User-Agent fragment

	Organizations *OrganizationsService
}

func (s *Service) userAgent() string {
	if s.UserAgent == "" {
		return googleapi.UserAgent
	}
	return googleapi.UserAgent + " " + s.UserAgent
}

func NewOrganizationsService(s *Service) *OrganizationsService {
	rs := &OrganizationsService{s: s}
	rs.Operations = NewOrganizationsOperationsService(s)
	return rs
}

type OrganizationsService struct {
	s *Service

	Operations *OrganizationsOperationsService
}

func NewOrganizationsOperationsService(s *Service) *OrganizationsOperationsService {
	rs := &OrganizationsOperationsService{s: s}
	return rs
}

type OrganizationsOperationsService struct {
	s *Service
}

// Empty: A generic empty message that you can re-use to avoid defining
// duplicated
// empty messages in your APIs. A typical example is to use it as the
// request
// or the response type of an API method. For instance:
//
//     service Foo {
//       rpc Bar(google.protobuf.Empty) returns
// (google.protobuf.Empty);
//     }
//
// The JSON representation for `Empty` is empty JSON object `{}`.
type Empty struct {
	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`
}

// Finding: Security Command Center finding.
//
// A finding is a record of assessment data like security, risk, health,
// or
// privacy, that is ingested into Security Command Center for
// presentation,
// notification, analysis, policy testing, and enforcement. For example,
// a
// cross-site scripting (XSS) vulnerability in an App Engine application
// is a
// finding.
type Finding struct {
	// Category: The additional taxonomy group within findings from a given
	// source.
	// This field is immutable after creation time.
	// Example: "XSS_FLASH_INJECTION"
	Category string `json:"category,omitempty"`

	// CreateTime: The time at which the finding was created in Security
	// Command Center.
	CreateTime string `json:"createTime,omitempty"`

	// EventTime: The time at which the event took place. For example, if
	// the finding
	// represents an open firewall it would capture the time the detector
	// believes
	// the firewall became open. The accuracy is determined by the detector.
	EventTime string `json:"eventTime,omitempty"`

	// ExternalUri: The URI that, if available, points to a web page outside
	// of Security
	// Command Center where additional information about the finding can be
	// found.
	// This field is guaranteed to be either empty or a well formed URL.
	ExternalUri string `json:"externalUri,omitempty"`

	// Name: The relative resource name of this finding.
	// See:
	// https://cloud.google.com/apis/design/resource_names#relative_reso
	// urce_name
	// Example:
	// "organizations/{organization_id}/sources/{source_id
	// }/findings/{finding_id}"
	Name string `json:"name,omitempty"`

	// Parent: The relative resource name of the source the finding belongs
	// to.
	// See:
	// https://cloud.google.com/apis/design/resource_names#relative_reso
	// urce_name
	// This field is immutable after creation time.
	// For example:
	// "organizations/{organization_id}/sources/{source_id}"
	Parent string `json:"parent,omitempty"`

	// ResourceName: For findings on Google Cloud resources, the full
	// resource
	// name of the Google Cloud resource this finding is for.
	// See:
	// https://cloud.google.com/apis/design/resource_names#full_resource
	// _name
	// When the finding is for a non-Google Cloud resource, the resourceName
	// can
	// be a customer or partner defined string. This field is immutable
	// after
	// creation time.
	ResourceName string `json:"resourceName,omitempty"`

	// SecurityMarks: Output only. User specified security marks. These
	// marks are entirely
	// managed by the user and come from the SecurityMarks resource that
	// belongs
	// to the finding.
	SecurityMarks *SecurityMarks `json:"securityMarks,omitempty"`

	// SourceProperties: Source specific properties. These properties are
	// managed by the source
	// that writes the finding. The key names in the source_properties map
	// must be
	// between 1 and 255 characters, and must start with a letter and
	// contain
	// alphanumeric characters or underscores only.
	SourceProperties googleapi.RawMessage `json:"sourceProperties,omitempty"`

	// State: The state of the finding.
	//
	// Possible values:
	//   "STATE_UNSPECIFIED" - Unspecified state.
	//   "ACTIVE" - The finding requires attention and has not been
	// addressed yet.
	//   "INACTIVE" - The finding has been fixed, triaged as a non-issue or
	// otherwise addressed
	// and is no longer active.
	State string `json:"state,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Category") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Category") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Finding) MarshalJSON() ([]byte, error) {
	type NoMethod Finding
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudSecuritycenterV1NotificationMessage: Cloud SCC's
// Notification
type GoogleCloudSecuritycenterV1NotificationMessage struct {
	// Finding: If it's a Finding based notification config, this field will
	// be
	// populated.
	Finding *Finding `json:"finding,omitempty"`

	// NotificationConfigName: Name of the notification config that
	// generated current notification.
	NotificationConfigName string `json:"notificationConfigName,omitempty"`

	// Resource: The Cloud resource tied to this notification's Finding.
	Resource *GoogleCloudSecuritycenterV1Resource `json:"resource,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Finding") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Finding") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudSecuritycenterV1NotificationMessage) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudSecuritycenterV1NotificationMessage
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudSecuritycenterV1Resource:
// Information related to the Google Cloud resource.
type GoogleCloudSecuritycenterV1Resource struct {
	// Name: The full resource name of the resource.
	// See:
	// https://cloud.google.com/apis/design/resource_names#full_resource
	// _name
	Name string `json:"name,omitempty"`

	// Parent: The full resource name of resource's parent.
	Parent string `json:"parent,omitempty"`

	// ParentDisplayName:
	// The human readable name of resource's parent.
	ParentDisplayName string `json:"parentDisplayName,omitempty"`

	// Project: The full resource name of project that the resource belongs
	// to.
	Project string `json:"project,omitempty"`

	// ProjectDisplayName:
	// The human readable name of project that the resource belongs to.
	ProjectDisplayName string `json:"projectDisplayName,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Name") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Name") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudSecuritycenterV1Resource) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudSecuritycenterV1Resource
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudSecuritycenterV1RunAssetDiscoveryResponse: Response of
// asset discovery run
type GoogleCloudSecuritycenterV1RunAssetDiscoveryResponse struct {
	// Duration: The duration between asset discovery run start and end
	Duration string `json:"duration,omitempty"`

	// State: The state of an asset discovery run.
	//
	// Possible values:
	//   "STATE_UNSPECIFIED" - Asset discovery run state was unspecified.
	//   "COMPLETED" - Asset discovery run completed successfully.
	//   "SUPERSEDED" - Asset discovery run was cancelled with tasks still
	// pending, as another
	// run for the same organization was started with a higher priority.
	//   "TERMINATED" - Asset discovery run was killed and terminated.
	State string `json:"state,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Duration") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Duration") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudSecuritycenterV1RunAssetDiscoveryResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudSecuritycenterV1RunAssetDiscoveryResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudSecuritycenterV1beta1RunAssetDiscoveryResponse: Response
// of asset discovery run
type GoogleCloudSecuritycenterV1beta1RunAssetDiscoveryResponse struct {
	// Duration: The duration between asset discovery run start and end
	Duration string `json:"duration,omitempty"`

	// State: The state of an asset discovery run.
	//
	// Possible values:
	//   "STATE_UNSPECIFIED" - Asset discovery run state was unspecified.
	//   "COMPLETED" - Asset discovery run completed successfully.
	//   "SUPERSEDED" - Asset discovery run was cancelled with tasks still
	// pending, as another
	// run for the same organization was started with a higher priority.
	//   "TERMINATED" - Asset discovery run was killed and terminated.
	State string `json:"state,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Duration") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Duration") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudSecuritycenterV1beta1RunAssetDiscoveryResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudSecuritycenterV1beta1RunAssetDiscoveryResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudSecuritycenterV1p1beta1Asset: Security Command Center
// representation of a Google Cloud
// resource.
//
// The Asset is a Security Command Center resource that captures
// information
// about a single Google Cloud resource. All modifications to an Asset
// are only
// within the context of Security Command Center and don't affect the
// referenced
// Google Cloud resource.
type GoogleCloudSecuritycenterV1p1beta1Asset struct {
	// CreateTime: The time at which the asset was created in Security
	// Command Center.
	CreateTime string `json:"createTime,omitempty"`

	// IamPolicy: Cloud IAM Policy information associated with the Google
	// Cloud resource
	// described by the Security Command Center asset. This information is
	// managed
	// and defined by the Google Cloud resource and cannot be modified by
	// the
	// user.
	IamPolicy *GoogleCloudSecuritycenterV1p1beta1IamPolicy `json:"iamPolicy,omitempty"`

	// Name: The relative resource name of this asset.
	// See:
	// https://cloud.google.com/apis/design/resource_names#relative_reso
	// urce_name
	// Example:
	// "organizations/{organization_id}/assets/{asset_id}"
	// .
	Name string `json:"name,omitempty"`

	// ResourceProperties: Resource managed properties. These properties are
	// managed and defined by
	// the Google Cloud resource and cannot be modified by the user.
	ResourceProperties googleapi.RawMessage `json:"resourceProperties,omitempty"`

	// SecurityCenterProperties: Security Command Center managed properties.
	// These properties are managed by
	// Security Command Center and cannot be modified by the user.
	SecurityCenterProperties *GoogleCloudSecuritycenterV1p1beta1SecurityCenterProperties `json:"securityCenterProperties,omitempty"`

	// SecurityMarks: User specified security marks. These marks are
	// entirely managed by the user
	// and come from the SecurityMarks resource that belongs to the asset.
	SecurityMarks *GoogleCloudSecuritycenterV1p1beta1SecurityMarks `json:"securityMarks,omitempty"`

	// UpdateTime: The time at which the asset was last updated, added, or
	// deleted in Cloud
	// SCC.
	UpdateTime string `json:"updateTime,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CreateTime") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CreateTime") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudSecuritycenterV1p1beta1Asset) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudSecuritycenterV1p1beta1Asset
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudSecuritycenterV1p1beta1Finding: Security Command Center
// finding.
//
// A finding is a record of assessment data (security, risk, health or
// privacy)
// ingested into Security Command Center for presentation,
// notification,
// analysis, policy testing, and enforcement. For example, an XSS
// vulnerability
// in an App Engine application is a finding.
type GoogleCloudSecuritycenterV1p1beta1Finding struct {
	// Category: The additional taxonomy group within findings from a given
	// source.
	// This field is immutable after creation time.
	// Example: "XSS_FLASH_INJECTION"
	Category string `json:"category,omitempty"`

	// CreateTime: The time at which the finding was created in Security
	// Command Center.
	CreateTime string `json:"createTime,omitempty"`

	// EventTime: The time at which the event took place. For example, if
	// the finding
	// represents an open firewall it would capture the time the detector
	// believes
	// the firewall became open. The accuracy is determined by the detector.
	EventTime string `json:"eventTime,omitempty"`

	// ExternalUri: The URI that, if available, points to a web page outside
	// of Security
	// Command Center where additional information about the finding can be
	// found.
	// This field is guaranteed to be either empty or a well formed URL.
	ExternalUri string `json:"externalUri,omitempty"`

	// Name: The relative resource name of this finding.
	// See:
	// https://cloud.google.com/apis/design/resource_names#relative_reso
	// urce_name
	// Example:
	// "organizations/{organization_id}/sources/{source_id
	// }/findings/{finding_id}"
	Name string `json:"name,omitempty"`

	// Parent: The relative resource name of the source the finding belongs
	// to.
	// See:
	// https://cloud.google.com/apis/design/resource_names#relative_reso
	// urce_name
	// This field is immutable after creation time.
	// For example:
	// "organizations/{organization_id}/sources/{source_id}"
	Parent string `json:"parent,omitempty"`

	// ResourceName: For findings on Google Cloud resources, the full
	// resource
	// name of the Google Cloud resource this finding is for.
	// See:
	// https://cloud.google.com/apis/design/resource_names#full_resource
	// _name
	// When the finding is for a non-Google Cloud resource, the resourceName
	// can
	// be a customer or partner defined string. This field is immutable
	// after
	// creation time.
	ResourceName string `json:"resourceName,omitempty"`

	// SecurityMarks: Output only. User specified security marks. These
	// marks are entirely
	// managed by the user and come from the SecurityMarks resource that
	// belongs
	// to the finding.
	SecurityMarks *GoogleCloudSecuritycenterV1p1beta1SecurityMarks `json:"securityMarks,omitempty"`

	// SourceProperties: Source specific properties. These properties are
	// managed by the source
	// that writes the finding. The key names in the source_properties map
	// must be
	// between 1 and 255 characters, and must start with a letter and
	// contain
	// alphanumeric characters or underscores only.
	SourceProperties googleapi.RawMessage `json:"sourceProperties,omitempty"`

	// State: The state of the finding.
	//
	// Possible values:
	//   "STATE_UNSPECIFIED" - Unspecified state.
	//   "ACTIVE" - The finding requires attention and has not been
	// addressed yet.
	//   "INACTIVE" - The finding has been fixed, triaged as a non-issue or
	// otherwise addressed
	// and is no longer active.
	State string `json:"state,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Category") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Category") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudSecuritycenterV1p1beta1Finding) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudSecuritycenterV1p1beta1Finding
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudSecuritycenterV1p1beta1IamPolicy: Cloud IAM Policy
// information associated with the Google Cloud resource
// described by the Security Command Center asset. This information is
// managed
// and defined by the Google Cloud resource and cannot be modified by
// the
// user.
type GoogleCloudSecuritycenterV1p1beta1IamPolicy struct {
	// PolicyBlob: The JSON representation of the Policy associated with the
	// asset.
	// See https://cloud.google.com/iam/docs/reference/rest/v1/Policy
	// for
	// format details.
	PolicyBlob string `json:"policyBlob,omitempty"`

	// ForceSendFields is a list of field names (e.g. "PolicyBlob") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "PolicyBlob") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudSecuritycenterV1p1beta1IamPolicy) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudSecuritycenterV1p1beta1IamPolicy
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudSecuritycenterV1p1beta1NotificationMessage: Security
// Command Center's Notification
type GoogleCloudSecuritycenterV1p1beta1NotificationMessage struct {
	// Finding: If it's a Finding based notification config, this field will
	// be
	// populated.
	Finding *GoogleCloudSecuritycenterV1p1beta1Finding `json:"finding,omitempty"`

	// NotificationConfigName: Name of the notification config that
	// generated current notification.
	NotificationConfigName string `json:"notificationConfigName,omitempty"`

	// Resource: The Cloud resource tied to the notification.
	Resource *GoogleCloudSecuritycenterV1p1beta1Resource `json:"resource,omitempty"`

	// TemporalAsset: If it's an asset based notification config, this field
	// will be
	// populated.
	TemporalAsset *GoogleCloudSecuritycenterV1p1beta1TemporalAsset `json:"temporalAsset,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Finding") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Finding") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudSecuritycenterV1p1beta1NotificationMessage) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudSecuritycenterV1p1beta1NotificationMessage
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudSecuritycenterV1p1beta1Resource:
// Information related to the Google Cloud resource.
type GoogleCloudSecuritycenterV1p1beta1Resource struct {
	// Name: The full resource name of the resource.
	// See:
	// https://cloud.google.com/apis/design/resource_names#full_resource
	// _name
	Name string `json:"name,omitempty"`

	// Parent: The full resource name of resource's parent.
	Parent string `json:"parent,omitempty"`

	// ParentDisplayName:
	// The human readable name of resource's parent.
	ParentDisplayName string `json:"parentDisplayName,omitempty"`

	// Project: The full resource name of project that the resource belongs
	// to.
	Project string `json:"project,omitempty"`

	// ProjectDisplayName:
	// The human readable name of project that the resource belongs to.
	ProjectDisplayName string `json:"projectDisplayName,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Name") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Name") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudSecuritycenterV1p1beta1Resource) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudSecuritycenterV1p1beta1Resource
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudSecuritycenterV1p1beta1RunAssetDiscoveryResponse: Response
// of asset discovery run
type GoogleCloudSecuritycenterV1p1beta1RunAssetDiscoveryResponse struct {
	// Duration: The duration between asset discovery run start and end
	Duration string `json:"duration,omitempty"`

	// State: The state of an asset discovery run.
	//
	// Possible values:
	//   "STATE_UNSPECIFIED" - Asset discovery run state was unspecified.
	//   "COMPLETED" - Asset discovery run completed successfully.
	//   "SUPERSEDED" - Asset discovery run was cancelled with tasks still
	// pending, as another
	// run for the same organization was started with a higher priority.
	//   "TERMINATED" - Asset discovery run was killed and terminated.
	State string `json:"state,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Duration") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Duration") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudSecuritycenterV1p1beta1RunAssetDiscoveryResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudSecuritycenterV1p1beta1RunAssetDiscoveryResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudSecuritycenterV1p1beta1SecurityCenterProperties: Security
// Command Center managed properties. These properties are managed
// by
// Security Command Center and cannot be modified by the user.
type GoogleCloudSecuritycenterV1p1beta1SecurityCenterProperties struct {
	// ResourceDisplayName: The user defined display name for this resource.
	ResourceDisplayName string `json:"resourceDisplayName,omitempty"`

	// ResourceName: The full resource name of the Google Cloud resource
	// this asset
	// represents. This field is immutable after create time.
	// See:
	// https://cloud.google.com/apis/design/resource_names#full_resource
	// _name
	ResourceName string `json:"resourceName,omitempty"`

	// ResourceOwners: Owners of the Google Cloud resource.
	ResourceOwners []string `json:"resourceOwners,omitempty"`

	// ResourceParent: The full resource name of the immediate parent of the
	// resource.
	// See:
	// https://cloud.google.com/apis/design/resource_names#full_resource
	// _name
	ResourceParent string `json:"resourceParent,omitempty"`

	// ResourceParentDisplayName: The user defined display name for the
	// parent of this resource.
	ResourceParentDisplayName string `json:"resourceParentDisplayName,omitempty"`

	// ResourceProject: The full resource name of the project the resource
	// belongs to.
	// See:
	// https://cloud.google.com/apis/design/resource_names#full_resource
	// _name
	ResourceProject string `json:"resourceProject,omitempty"`

	// ResourceProjectDisplayName: The user defined display name for the
	// project of this resource.
	ResourceProjectDisplayName string `json:"resourceProjectDisplayName,omitempty"`

	// ResourceType: The type of the Google Cloud resource. Examples
	// include: APPLICATION,
	// PROJECT, and ORGANIZATION. This is a case insensitive field defined
	// by
	// Security Command Center and/or the producer of the resource and
	// is
	// immutable after create time.
	ResourceType string `json:"resourceType,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ResourceDisplayName")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ResourceDisplayName") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudSecuritycenterV1p1beta1SecurityCenterProperties) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudSecuritycenterV1p1beta1SecurityCenterProperties
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudSecuritycenterV1p1beta1SecurityMarks: User specified
// security marks that are attached to the parent Security
// Command Center resource. Security marks are scoped within a Security
// Command
// Center organization -- they can be modified and viewed by all users
// who have
// proper permissions on the organization.
type GoogleCloudSecuritycenterV1p1beta1SecurityMarks struct {
	// Marks: Mutable user specified security marks belonging to the parent
	// resource.
	// Constraints are as follows:
	//
	//   * Keys and values are treated as case insensitive
	//   * Keys must be between 1 - 256 characters (inclusive)
	//   * Keys must be letters, numbers, underscores, or dashes
	//   * Values have leading and trailing whitespace trimmed, remaining
	//     characters must be between 1 - 4096 characters (inclusive)
	Marks map[string]string `json:"marks,omitempty"`

	// Name: The relative resource name of the SecurityMarks.
	// See:
	// https://cloud.google.com/apis/design/resource_names#relative_reso
	// urce_name
	// Examples:
	// "organizations/{organization_id}/assets/{asset_id}
	// /securityMarks"
	// "organizations/{organization_id}/sources/{source_id}/f
	// indings/{finding_id}/securityMarks".
	Name string `json:"name,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Marks") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Marks") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudSecuritycenterV1p1beta1SecurityMarks) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudSecuritycenterV1p1beta1SecurityMarks
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudSecuritycenterV1p1beta1TemporalAsset: Wrapper over asset
// object that also captures the state change for the asset
// e.g. if it was a newly created asset vs updated or deleted asset.
type GoogleCloudSecuritycenterV1p1beta1TemporalAsset struct {
	// Asset: Asset data that includes attributes, properties and marks
	// about the asset.
	Asset *GoogleCloudSecuritycenterV1p1beta1Asset `json:"asset,omitempty"`

	// ChangeType: Represents if the asset was created/updated/deleted.
	//
	// Possible values:
	//   "CHANGE_TYPE_UNSPECIFIED" - Unspecified or default.
	//   "CREATED" - Newly created Asset
	//   "UPDATED" - Asset was updated.
	//   "DELETED" - Asset was deleted.
	ChangeType string `json:"changeType,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Asset") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Asset") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudSecuritycenterV1p1beta1TemporalAsset) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudSecuritycenterV1p1beta1TemporalAsset
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ListOperationsResponse: The response message for
// Operations.ListOperations.
type ListOperationsResponse struct {
	// NextPageToken: The standard List next-page token.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// Operations: A list of operations that matches the specified filter in
	// the request.
	Operations []*Operation `json:"operations,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "NextPageToken") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "NextPageToken") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ListOperationsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListOperationsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Operation: This resource represents a long-running operation that is
// the result of a
// network API call.
type Operation struct {
	// Done: If the value is `false`, it means the operation is still in
	// progress.
	// If `true`, the operation is completed, and either `error` or
	// `response` is
	// available.
	Done bool `json:"done,omitempty"`

	// Error: The error result of the operation in case of failure or
	// cancellation.
	Error *Status `json:"error,omitempty"`

	// Metadata: Service-specific metadata associated with the operation.
	// It typically
	// contains progress information and common metadata such as create
	// time.
	// Some services might not provide such metadata.  Any method that
	// returns a
	// long-running operation should document the metadata type, if any.
	Metadata googleapi.RawMessage `json:"metadata,omitempty"`

	// Name: The server-assigned name, which is only unique within the same
	// service that
	// originally returns it. If you use the default HTTP mapping,
	// the
	// `name` should be a resource name ending with
	// `operations/{unique_id}`.
	Name string `json:"name,omitempty"`

	// Response: The normal response of the operation in case of success.
	// If the original
	// method returns no data on success, such as `Delete`, the response
	// is
	// `google.protobuf.Empty`.  If the original method is
	// standard
	// `Get`/`Create`/`Update`, the response should be the resource.  For
	// other
	// methods, the response should have the type `XxxResponse`, where
	// `Xxx`
	// is the original method name.  For example, if the original method
	// name
	// is `TakeSnapshot()`, the inferred response type
	// is
	// `TakeSnapshotResponse`.
	Response googleapi.RawMessage `json:"response,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Done") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Done") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Operation) MarshalJSON() ([]byte, error) {
	type NoMethod Operation
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SecurityMarks: User specified security marks that are attached to the
// parent Security
// Command Center resource. Security marks are scoped within a Security
// Command
// Center organization -- they can be modified and viewed by all users
// who have
// proper permissions on the organization.
type SecurityMarks struct {
	// Marks: Mutable user specified security marks belonging to the parent
	// resource.
	// Constraints are as follows:
	//
	//   * Keys and values are treated as case insensitive
	//   * Keys must be between 1 - 256 characters (inclusive)
	//   * Keys must be letters, numbers, underscores, or dashes
	//   * Values have leading and trailing whitespace trimmed, remaining
	//     characters must be between 1 - 4096 characters (inclusive)
	Marks map[string]string `json:"marks,omitempty"`

	// Name: The relative resource name of the SecurityMarks.
	// See:
	// https://cloud.google.com/apis/design/resource_names#relative_reso
	// urce_name
	// Examples:
	// "organizations/{organization_id}/assets/{asset_id}
	// /securityMarks"
	// "organizations/{organization_id}/sources/{source_id}/f
	// indings/{finding_id}/securityMarks".
	Name string `json:"name,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Marks") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Marks") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *SecurityMarks) MarshalJSON() ([]byte, error) {
	type NoMethod SecurityMarks
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Status: The `Status` type defines a logical error model that is
// suitable for
// different programming environments, including REST APIs and RPC APIs.
// It is
// used by [gRPC](https://github.com/grpc). Each `Status` message
// contains
// three pieces of data: error code, error message, and error
// details.
//
// You can find out more about this error model and how to work with it
// in the
// [API Design Guide](https://cloud.google.com/apis/design/errors).
type Status struct {
	// Code: The status code, which should be an enum value of
	// google.rpc.Code.
	Code int64 `json:"code,omitempty"`

	// Details: A list of messages that carry the error details.  There is a
	// common set of
	// message types for APIs to use.
	Details []googleapi.RawMessage `json:"details,omitempty"`

	// Message: A developer-facing error message, which should be in
	// English. Any
	// user-facing error message should be localized and sent in
	// the
	// google.rpc.Status.details field, or localized by the client.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Status) MarshalJSON() ([]byte, error) {
	type NoMethod Status
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// method id "securitycenter.organizations.operations.cancel":

type OrganizationsOperationsCancelCall struct {
	s          *Service
	name       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Cancel: Starts asynchronous cancellation on a long-running operation.
//  The server
// makes a best effort to cancel the operation, but success is
// not
// guaranteed.  If the server doesn't support this method, it
// returns
// `google.rpc.Code.UNIMPLEMENTED`.  Clients can
// use
// Operations.GetOperation or
// other methods to check whether the cancellation succeeded or whether
// the
// operation completed despite cancellation. On successful
// cancellation,
// the operation is not deleted; instead, it becomes an operation
// with
// an Operation.error value with a google.rpc.Status.code of
// 1,
// corresponding to `Code.CANCELLED`.
func (r *OrganizationsOperationsService) Cancel(name string) *OrganizationsOperationsCancelCall {
	c := &OrganizationsOperationsCancelCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *OrganizationsOperationsCancelCall) Fields(s ...googleapi.Field) *OrganizationsOperationsCancelCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *OrganizationsOperationsCancelCall) Context(ctx context.Context) *OrganizationsOperationsCancelCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *OrganizationsOperationsCancelCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsOperationsCancelCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200609")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1p1alpha1/{+name}:cancel")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "securitycenter.organizations.operations.cancel" call.
// Exactly one of *Empty or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Empty.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *OrganizationsOperationsCancelCall) Do(opts ...googleapi.CallOption) (*Empty, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Empty{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Starts asynchronous cancellation on a long-running operation.  The server\nmakes a best effort to cancel the operation, but success is not\nguaranteed.  If the server doesn't support this method, it returns\n`google.rpc.Code.UNIMPLEMENTED`.  Clients can use\nOperations.GetOperation or\nother methods to check whether the cancellation succeeded or whether the\noperation completed despite cancellation. On successful cancellation,\nthe operation is not deleted; instead, it becomes an operation with\nan Operation.error value with a google.rpc.Status.code of 1,\ncorresponding to `Code.CANCELLED`.",
	//   "flatPath": "v1p1alpha1/organizations/{organizationsId}/operations/{operationsId}:cancel",
	//   "httpMethod": "POST",
	//   "id": "securitycenter.organizations.operations.cancel",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the operation resource to be cancelled.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/operations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1p1alpha1/{+name}:cancel",
	//   "response": {
	//     "$ref": "Empty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "securitycenter.organizations.operations.delete":

type OrganizationsOperationsDeleteCall struct {
	s          *Service
	name       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes a long-running operation. This method indicates that
// the client is
// no longer interested in the operation result. It does not cancel
// the
// operation. If the server doesn't support this method, it
// returns
// `google.rpc.Code.UNIMPLEMENTED`.
func (r *OrganizationsOperationsService) Delete(name string) *OrganizationsOperationsDeleteCall {
	c := &OrganizationsOperationsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *OrganizationsOperationsDeleteCall) Fields(s ...googleapi.Field) *OrganizationsOperationsDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *OrganizationsOperationsDeleteCall) Context(ctx context.Context) *OrganizationsOperationsDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *OrganizationsOperationsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsOperationsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200609")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1p1alpha1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "securitycenter.organizations.operations.delete" call.
// Exactly one of *Empty or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Empty.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *OrganizationsOperationsDeleteCall) Do(opts ...googleapi.CallOption) (*Empty, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Empty{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes a long-running operation. This method indicates that the client is\nno longer interested in the operation result. It does not cancel the\noperation. If the server doesn't support this method, it returns\n`google.rpc.Code.UNIMPLEMENTED`.",
	//   "flatPath": "v1p1alpha1/organizations/{organizationsId}/operations/{operationsId}",
	//   "httpMethod": "DELETE",
	//   "id": "securitycenter.organizations.operations.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the operation resource to be deleted.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/operations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1p1alpha1/{+name}",
	//   "response": {
	//     "$ref": "Empty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "securitycenter.organizations.operations.get":

type OrganizationsOperationsGetCall struct {
	s            *Service
	name         string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets the latest state of a long-running operation.  Clients can
// use this
// method to poll the operation result at intervals as recommended by
// the API
// service.
func (r *OrganizationsOperationsService) Get(name string) *OrganizationsOperationsGetCall {
	c := &OrganizationsOperationsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *OrganizationsOperationsGetCall) Fields(s ...googleapi.Field) *OrganizationsOperationsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *OrganizationsOperationsGetCall) IfNoneMatch(entityTag string) *OrganizationsOperationsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *OrganizationsOperationsGetCall) Context(ctx context.Context) *OrganizationsOperationsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *OrganizationsOperationsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsOperationsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200609")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1p1alpha1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "securitycenter.organizations.operations.get" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *OrganizationsOperationsGetCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets the latest state of a long-running operation.  Clients can use this\nmethod to poll the operation result at intervals as recommended by the API\nservice.",
	//   "flatPath": "v1p1alpha1/organizations/{organizationsId}/operations/{operationsId}",
	//   "httpMethod": "GET",
	//   "id": "securitycenter.organizations.operations.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the operation resource.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/operations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1p1alpha1/{+name}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "securitycenter.organizations.operations.list":

type OrganizationsOperationsListCall struct {
	s            *Service
	name         string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Lists operations that match the specified filter in the
// request. If the
// server doesn't support this method, it returns
// `UNIMPLEMENTED`.
//
// NOTE: the `name` binding allows API services to override the
// binding
// to use different resource name schemes, such as `users/*/operations`.
// To
// override the binding, API services can add a binding such
// as
// "/v1/{name=users/*}/operations" to their service configuration.
// For backwards compatibility, the default name includes the
// operations
// collection id, however overriding users must ensure the name
// binding
// is the parent resource, without the operations collection id.
func (r *OrganizationsOperationsService) List(name string) *OrganizationsOperationsListCall {
	c := &OrganizationsOperationsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// Filter sets the optional parameter "filter": The standard list
// filter.
func (c *OrganizationsOperationsListCall) Filter(filter string) *OrganizationsOperationsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// PageSize sets the optional parameter "pageSize": The standard list
// page size.
func (c *OrganizationsOperationsListCall) PageSize(pageSize int64) *OrganizationsOperationsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The standard list
// page token.
func (c *OrganizationsOperationsListCall) PageToken(pageToken string) *OrganizationsOperationsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *OrganizationsOperationsListCall) Fields(s ...googleapi.Field) *OrganizationsOperationsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *OrganizationsOperationsListCall) IfNoneMatch(entityTag string) *OrganizationsOperationsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *OrganizationsOperationsListCall) Context(ctx context.Context) *OrganizationsOperationsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *OrganizationsOperationsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsOperationsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200609")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1p1alpha1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "securitycenter.organizations.operations.list" call.
// Exactly one of *ListOperationsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListOperationsResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *OrganizationsOperationsListCall) Do(opts ...googleapi.CallOption) (*ListOperationsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ListOperationsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Lists operations that match the specified filter in the request. If the\nserver doesn't support this method, it returns `UNIMPLEMENTED`.\n\nNOTE: the `name` binding allows API services to override the binding\nto use different resource name schemes, such as `users/*/operations`. To\noverride the binding, API services can add a binding such as\n`\"/v1/{name=users/*}/operations\"` to their service configuration.\nFor backwards compatibility, the default name includes the operations\ncollection id, however overriding users must ensure the name binding\nis the parent resource, without the operations collection id.",
	//   "flatPath": "v1p1alpha1/organizations/{organizationsId}/operations",
	//   "httpMethod": "GET",
	//   "id": "securitycenter.organizations.operations.list",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "The standard list filter.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "name": {
	//       "description": "The name of the operation's parent resource.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/operations$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "The standard list page size.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The standard list page token.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1p1alpha1/{+name}",
	//   "response": {
	//     "$ref": "ListOperationsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *OrganizationsOperationsListCall) Pages(ctx context.Context, f func(*ListOperationsResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}
