// 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 Cloud 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/v1"
//   ...
//   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/v1"

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:v1"
const apiName = "securitycenter"
const apiVersion = "v1"
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.Assets = NewOrganizationsAssetsService(s)
	rs.NotificationConfigs = NewOrganizationsNotificationConfigsService(s)
	rs.Operations = NewOrganizationsOperationsService(s)
	rs.Sources = NewOrganizationsSourcesService(s)
	return rs
}

type OrganizationsService struct {
	s *Service

	Assets *OrganizationsAssetsService

	NotificationConfigs *OrganizationsNotificationConfigsService

	Operations *OrganizationsOperationsService

	Sources *OrganizationsSourcesService
}

func NewOrganizationsAssetsService(s *Service) *OrganizationsAssetsService {
	rs := &OrganizationsAssetsService{s: s}
	return rs
}

type OrganizationsAssetsService struct {
	s *Service
}

func NewOrganizationsNotificationConfigsService(s *Service) *OrganizationsNotificationConfigsService {
	rs := &OrganizationsNotificationConfigsService{s: s}
	return rs
}

type OrganizationsNotificationConfigsService struct {
	s *Service
}

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

type OrganizationsOperationsService struct {
	s *Service
}

func NewOrganizationsSourcesService(s *Service) *OrganizationsSourcesService {
	rs := &OrganizationsSourcesService{s: s}
	rs.Findings = NewOrganizationsSourcesFindingsService(s)
	return rs
}

type OrganizationsSourcesService struct {
	s *Service

	Findings *OrganizationsSourcesFindingsService
}

func NewOrganizationsSourcesFindingsService(s *Service) *OrganizationsSourcesFindingsService {
	rs := &OrganizationsSourcesFindingsService{s: s}
	return rs
}

type OrganizationsSourcesFindingsService struct {
	s *Service
}

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

	// IamPolicy: IAM Policy information associated with the GCP resource
	// described by the
	// Cloud SCC asset. This information is managed and defined by the
	// GCP
	// resource and cannot be modified by the user.
	IamPolicy *IamPolicy `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 GCP resource and cannot be modified by the user.
	ResourceProperties googleapi.RawMessage `json:"resourceProperties,omitempty"`

	// SecurityCenterProperties: Cloud SCC managed properties. These
	// properties are managed by
	// Cloud SCC and cannot be modified by the user.
	SecurityCenterProperties *SecurityCenterProperties `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 *SecurityMarks `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 *Asset) MarshalJSON() ([]byte, error) {
	type NoMethod Asset
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AssetDiscoveryConfig: The configuration used for Asset Discovery
// runs.
type AssetDiscoveryConfig struct {
	// InclusionMode: The mode to use for filtering asset discovery.
	//
	// Possible values:
	//   "INCLUSION_MODE_UNSPECIFIED" - Unspecified. Setting the mode with
	// this value will disable
	// inclusion/exclusion filtering for Asset Discovery.
	//   "INCLUDE_ONLY" - Asset Discovery will capture only the resources
	// within the projects
	// specified. All other resources will be ignored.
	//   "EXCLUDE" - Asset Discovery will ignore all resources under the
	// projects specified.
	// All other resources will be retrieved.
	InclusionMode string `json:"inclusionMode,omitempty"`

	// ProjectIds: The project ids to use for filtering asset discovery.
	ProjectIds []string `json:"projectIds,omitempty"`

	// ForceSendFields is a list of field names (e.g. "InclusionMode") 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. "InclusionMode") 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 *AssetDiscoveryConfig) MarshalJSON() ([]byte, error) {
	type NoMethod AssetDiscoveryConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AuditConfig: Specifies the audit configuration for a service.
// The configuration determines which permission types are logged, and
// what
// identities, if any, are exempted from logging.
// An AuditConfig must have one or more AuditLogConfigs.
//
// If there are AuditConfigs for both `allServices` and a specific
// service,
// the union of the two AuditConfigs is used for that service: the
// log_types
// specified in each AuditConfig are enabled, and the exempted_members
// in each
// AuditLogConfig are exempted.
//
// Example Policy with multiple AuditConfigs:
//
//     {
//       "audit_configs": [
//         {
//           "service": "allServices"
//           "audit_log_configs": [
//             {
//               "log_type": "DATA_READ",
//               "exempted_members": [
//                 "user:jose@example.com"
//               ]
//             },
//             {
//               "log_type": "DATA_WRITE",
//             },
//             {
//               "log_type": "ADMIN_READ",
//             }
//           ]
//         },
//         {
//           "service": "sampleservice.googleapis.com"
//           "audit_log_configs": [
//             {
//               "log_type": "DATA_READ",
//             },
//             {
//               "log_type": "DATA_WRITE",
//               "exempted_members": [
//                 "user:aliya@example.com"
//               ]
//             }
//           ]
//         }
//       ]
//     }
//
// For sampleservice, this policy enables DATA_READ, DATA_WRITE and
// ADMIN_READ
// logging. It also exempts jose@example.com from DATA_READ logging,
// and
// aliya@example.com from DATA_WRITE logging.
type AuditConfig struct {
	// AuditLogConfigs: The configuration for logging of each type of
	// permission.
	AuditLogConfigs []*AuditLogConfig `json:"auditLogConfigs,omitempty"`

	// Service: Specifies a service that will be enabled for audit
	// logging.
	// For example, `storage.googleapis.com`,
	// `cloudsql.googleapis.com`.
	// `allServices` is a special value that covers all services.
	Service string `json:"service,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AuditLogConfigs") 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. "AuditLogConfigs") 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 *AuditConfig) MarshalJSON() ([]byte, error) {
	type NoMethod AuditConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AuditLogConfig: Provides the configuration for logging a type of
// permissions.
// Example:
//
//     {
//       "audit_log_configs": [
//         {
//           "log_type": "DATA_READ",
//           "exempted_members": [
//             "user:jose@example.com"
//           ]
//         },
//         {
//           "log_type": "DATA_WRITE",
//         }
//       ]
//     }
//
// This enables 'DATA_READ' and 'DATA_WRITE' logging, while
// exempting
// jose@example.com from DATA_READ logging.
type AuditLogConfig struct {
	// ExemptedMembers: Specifies the identities that do not cause logging
	// for this type of
	// permission.
	// Follows the same format of Binding.members.
	ExemptedMembers []string `json:"exemptedMembers,omitempty"`

	// LogType: The log type that this config enables.
	//
	// Possible values:
	//   "LOG_TYPE_UNSPECIFIED" - Default case. Should never be this.
	//   "ADMIN_READ" - Admin reads. Example: CloudIAM getIamPolicy
	//   "DATA_WRITE" - Data writes. Example: CloudSQL Users create
	//   "DATA_READ" - Data reads. Example: CloudSQL Users list
	LogType string `json:"logType,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ExemptedMembers") 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. "ExemptedMembers") 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 *AuditLogConfig) MarshalJSON() ([]byte, error) {
	type NoMethod AuditLogConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Binding: Associates `members` with a `role`.
type Binding struct {
	// Condition: The condition that is associated with this binding.
	// NOTE: An unsatisfied condition will not allow user access via
	// current
	// binding. Different bindings, including their conditions, are
	// examined
	// independently.
	Condition *Expr `json:"condition,omitempty"`

	// Members: Specifies the identities requesting access for a Cloud
	// Platform resource.
	// `members` can have the following values:
	//
	// * `allUsers`: A special identifier that represents anyone who is
	//    on the internet; with or without a Google account.
	//
	// * `allAuthenticatedUsers`: A special identifier that represents
	// anyone
	//    who is authenticated with a Google account or a service
	// account.
	//
	// * `user:{emailid}`: An email address that represents a specific
	// Google
	//    account. For example, `alice@example.com` .
	//
	//
	// * `serviceAccount:{emailid}`: An email address that represents a
	// service
	//    account. For example,
	// `my-other-app@appspot.gserviceaccount.com`.
	//
	// * `group:{emailid}`: An email address that represents a Google
	// group.
	//    For example, `admins@example.com`.
	//
	// * `deleted:user:{emailid}?uid={uniqueid}`: An email address (plus
	// unique
	//    identifier) representing a user that has been recently deleted.
	// For
	//    example, `alice@example.com?uid=123456789012345678901`. If the
	// user is
	//    recovered, this value reverts to `user:{emailid}` and the
	// recovered user
	//    retains the role in the binding.
	//
	// * `deleted:serviceAccount:{emailid}?uid={uniqueid}`: An email address
	// (plus
	//    unique identifier) representing a service account that has been
	// recently
	//    deleted. For example,
	//
	// `my-other-app@appspot.gserviceaccount.com?uid=123456789012345678901`.
	//
	//    If the service account is undeleted, this value reverts to
	//    `serviceAccount:{emailid}` and the undeleted service account
	// retains the
	//    role in the binding.
	//
	// * `deleted:group:{emailid}?uid={uniqueid}`: An email address (plus
	// unique
	//    identifier) representing a Google group that has been recently
	//    deleted. For example,
	// `admins@example.com?uid=123456789012345678901`. If
	//    the group is recovered, this value reverts to `group:{emailid}`
	// and the
	//    recovered group retains the role in the binding.
	//
	//
	// * `domain:{domain}`: The G Suite domain (primary) that represents all
	// the
	//    users of that domain. For example, `google.com` or
	// `example.com`.
	//
	//
	Members []string `json:"members,omitempty"`

	// Role: Role that is assigned to `members`.
	// For example, `roles/viewer`, `roles/editor`, or `roles/owner`.
	Role string `json:"role,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Condition") 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. "Condition") 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 *Binding) MarshalJSON() ([]byte, error) {
	type NoMethod Binding
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// 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:"-"`
}

// Expr: Represents a textual expression in the Common Expression
// Language (CEL)
// syntax. CEL is a C-like expression language. The syntax and semantics
// of CEL
// are documented at https://github.com/google/cel-spec.
//
// Example (Comparison):
//
//     title: "Summary size limit"
//     description: "Determines if a summary is less than 100 chars"
//     expression: "document.summary.size() < 100"
//
// Example (Equality):
//
//     title: "Requestor is owner"
//     description: "Determines if requestor is the document owner"
//     expression: "document.owner ==
// request.auth.claims.email"
//
// Example (Logic):
//
//     title: "Public documents"
//     description: "Determine whether the document should be publicly
// visible"
//     expression: "document.type != 'private' && document.type !=
// 'internal'"
//
// Example (Data Manipulation):
//
//     title: "Notification string"
//     description: "Create a notification string with a timestamp."
//     expression: "'New message received at ' +
// string(document.create_time)"
//
// The exact variables and functions that may be referenced within an
// expression
// are determined by the service that evaluates it. See the
// service
// documentation for additional information.
type Expr struct {
	// Description: Optional. Description of the expression. This is a
	// longer text which
	// describes the expression, e.g. when hovered over it in a UI.
	Description string `json:"description,omitempty"`

	// Expression: Textual representation of an expression in Common
	// Expression Language
	// syntax.
	Expression string `json:"expression,omitempty"`

	// Location: Optional. String indicating the location of the expression
	// for error
	// reporting, e.g. a file name and a position in the file.
	Location string `json:"location,omitempty"`

	// Title: Optional. Title for the expression, i.e. a short string
	// describing
	// its purpose. This can be used e.g. in UIs which allow to enter
	// the
	// expression.
	Title string `json:"title,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Description") 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. "Description") 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 *Expr) MarshalJSON() ([]byte, error) {
	type NoMethod Expr
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Finding: Cloud Security Command Center (Cloud SCC) finding.
//
// A finding is a record of assessment data like security, risk, health,
// or
// privacy, that is ingested into Cloud SCC 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 Cloud SCC.
	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 Cloud SCC
	// 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 Platform (GCP) resources,
	// the full resource
	// name of the GCP resource this finding is for.
	// See:
	// https://cloud.google.com/apis/design/resource_names#full_resource
	// _name
	// When the finding is for a non-GCP 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"`

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

	// 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)
}

// GetIamPolicyRequest: Request message for `GetIamPolicy` method.
type GetIamPolicyRequest struct {
	// Options: OPTIONAL: A `GetPolicyOptions` object for specifying options
	// to
	// `GetIamPolicy`. This field is only used by Cloud IAM.
	Options *GetPolicyOptions `json:"options,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Options") 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. "Options") 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 *GetIamPolicyRequest) MarshalJSON() ([]byte, error) {
	type NoMethod GetIamPolicyRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GetPolicyOptions: Encapsulates settings provided to GetIamPolicy.
type GetPolicyOptions struct {
	// RequestedPolicyVersion: Optional. The policy format version to be
	// returned.
	//
	// Valid values are 0, 1, and 3. Requests specifying an invalid value
	// will be
	// rejected.
	//
	// Requests for policies with any conditional bindings must specify
	// version 3.
	// Policies without any conditional bindings may specify any valid value
	// or
	// leave the field unset.
	RequestedPolicyVersion int64 `json:"requestedPolicyVersion,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "RequestedPolicyVersion") 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. "RequestedPolicyVersion")
	// 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 *GetPolicyOptions) MarshalJSON() ([]byte, error) {
	type NoMethod GetPolicyOptions
	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"`

	// 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)
}

// 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: Cloud Security Command
// Center's (Cloud SCC) representation of a Google Cloud
// Platform (GCP) resource.
//
// The Asset is a Cloud SCC resource that captures information about a
// single
// GCP resource. All modifications to an Asset are only within the
// context of
// Cloud SCC and don't affect the referenced GCP resource.
type GoogleCloudSecuritycenterV1p1beta1Asset struct {
	// CreateTime: The time at which the asset was created in Cloud SCC.
	CreateTime string `json:"createTime,omitempty"`

	// IamPolicy: IAM Policy information associated with the GCP resource
	// described by the
	// Cloud SCC asset. This information is managed and defined by the
	// GCP
	// 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 GCP resource and cannot be modified by the user.
	ResourceProperties googleapi.RawMessage `json:"resourceProperties,omitempty"`

	// SecurityCenterProperties: Cloud SCC managed properties. These
	// properties are managed by
	// Cloud SCC 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: Cloud Security Command
// Center (Cloud SCC) finding.
//
// A finding is a record of assessment data (security, risk, health or
// privacy)
// ingested into Cloud SCC 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 Cloud SCC.
	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 Cloud SCC
	// 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 Platform (GCP) resources,
	// the full resource
	// name of the GCP resource this finding is for.
	// See:
	// https://cloud.google.com/apis/design/resource_names#full_resource
	// _name
	// When the finding is for a non-GCP 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: IAM Policy information
// associated with the GCP resource described by the
// Cloud SCC asset. This information is managed and defined by the
// GCP
// 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/reference/rest/v1p1beta1/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: Cloud SCC'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"`

	// 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)
}

// 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: Cloud SCC
// managed properties. These properties are managed by Cloud SCC
// 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 GCP 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 GCP resource. Examples include:
	// APPLICATION,
	// PROJECT, and ORGANIZATION. This is a case insensitive field defined
	// by
	// Cloud SCC 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 Cloud Security
// Command Center (Cloud SCC) resource. Security marks are scoped within
// a Cloud
// SCC 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)
}

// GroupAssetsRequest: Request message for grouping by assets.
type GroupAssetsRequest struct {
	// CompareDuration: When compare_duration is set, the GroupResult's
	// "state_change" property is
	// updated to indicate whether the asset was added, removed, or
	// remained
	// present during the compare_duration period of time that precedes
	// the
	// read_time. This is the time between (read_time - compare_duration)
	// and
	// read_time.
	//
	// The state change value is derived based on the presence of the asset
	// at the
	// two points in time. Intermediate state changes between the two times
	// don't
	// affect the result. For example, the results aren't affected if the
	// asset is
	// removed and re-created again.
	//
	// Possible "state_change" values when compare_duration is specified:
	//
	// * "ADDED":   indicates that the asset was not present at the start
	// of
	//                compare_duration, but present at reference_time.
	// * "REMOVED": indicates that the asset was present at the start of
	//                compare_duration, but not present at reference_time.
	// * "ACTIVE":  indicates that the asset was present at both the
	//                start and the end of the time period defined by
	//                compare_duration and reference_time.
	//
	// If compare_duration is not specified, then the only possible
	// state_change
	// is "UNUSED", which will be the state_change set for all assets
	// present at
	// read_time.
	//
	// If this field is set then `state_change` must be a specified field
	// in
	// `group_by`.
	CompareDuration string `json:"compareDuration,omitempty"`

	// Filter: Expression that defines the filter to apply across
	// assets.
	// The expression is a list of zero or more restrictions combined via
	// logical
	// operators `AND` and `OR`.
	// Parentheses are supported, and `OR` has higher precedence than
	// `AND`.
	//
	// Restrictions have the form `<field> <operator> <value>` and may have
	// a `-`
	// character in front of them to indicate negation. The fields map to
	// those
	// defined in the Asset resource. Examples include:
	//
	// * name
	// * security_center_properties.resource_name
	// * resource_properties.a_property
	// * security_marks.marks.marka
	//
	// The supported operators are:
	//
	// * `=` for all value types.
	// * `>`, `<`, `>=`, `<=` for integer values.
	// * `:`, meaning substring matching, for strings.
	//
	// The supported value types are:
	//
	// * string literals in quotes.
	// * integer literals without quotes.
	// * boolean literals `true` and `false` without quotes.
	//
	// The following field and operator combinations are supported:
	//
	// * name: `=`
	// * update_time: `=`, `>`, `<`, `>=`, `<=`
	//
	//   Usage: This should be milliseconds since epoch or an RFC3339
	// string.
	//   Examples:
	//     "update_time = \"2019-06-10T16:07:18-07:00\""
	//     "update_time = 1560208038000"
	//
	// * create_time: `=`, `>`, `<`, `>=`, `<=`
	//
	//   Usage: This should be milliseconds since epoch or an RFC3339
	// string.
	//   Examples:
	//     "create_time = \"2019-06-10T16:07:18-07:00\""
	//     "create_time = 1560208038000"
	//
	// * iam_policy.policy_blob: `=`, `:`
	// * resource_properties: `=`, `:`, `>`, `<`, `>=`, `<=`
	// * security_marks.marks: `=`, `:`
	// * security_center_properties.resource_name: `=`, `:`
	// * security_center_properties.resource_display_name: `=`, `:`
	// * security_center_properties.resource_type: `=`, `:`
	// * security_center_properties.resource_parent: `=`, `:`
	// * security_center_properties.resource_parent_display_name: `=`, `:`
	// * security_center_properties.resource_project: `=`, `:`
	// * security_center_properties.resource_project_display_name: `=`,
	// `:`
	// * security_center_properties.resource_owners: `=`, `:`
	//
	// For example, `resource_properties.size = 100` is a valid filter
	// string.
	Filter string `json:"filter,omitempty"`

	// GroupBy: Required. Expression that defines what assets fields to use
	// for grouping. The string
	// value should follow SQL syntax: comma separated list of fields.
	// For
	// example:
	// "security_center_properties.resource_project,security_cen
	// ter_properties.project".
	//
	// The following fields are supported when compare_duration is not
	// set:
	//
	// * security_center_properties.resource_project
	// * security_center_properties.resource_project_display_name
	// * security_center_properties.resource_type
	// * security_center_properties.resource_parent
	// * security_center_properties.resource_parent_display_name
	//
	// The following fields are supported when compare_duration is set:
	//
	// * security_center_properties.resource_type
	// * security_center_properties.resource_project_display_name
	// * security_center_properties.resource_parent_display_name
	GroupBy string `json:"groupBy,omitempty"`

	// PageSize: The maximum number of results to return in a single
	// response. Default is
	// 10, minimum is 1, maximum is 1000.
	PageSize int64 `json:"pageSize,omitempty"`

	// PageToken: The value returned by the last `GroupAssetsResponse`;
	// indicates
	// that this is a continuation of a prior `GroupAssets` call, and that
	// the
	// system should return the next page of data.
	PageToken string `json:"pageToken,omitempty"`

	// ReadTime: Time used as a reference point when filtering assets. The
	// filter is limited
	// to assets existing at the supplied time and their values are those at
	// that
	// specific time. Absence of this field will default to the API's
	// version of
	// NOW.
	ReadTime string `json:"readTime,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CompareDuration") 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. "CompareDuration") 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 *GroupAssetsRequest) MarshalJSON() ([]byte, error) {
	type NoMethod GroupAssetsRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GroupAssetsResponse: Response message for grouping by assets.
type GroupAssetsResponse struct {
	// GroupByResults: Group results. There exists an element for each
	// existing unique
	// combination of property/values. The element contains a count for the
	// number
	// of times those specific property/values appear.
	GroupByResults []*GroupResult `json:"groupByResults,omitempty"`

	// NextPageToken: Token to retrieve the next page of results, or empty
	// if there are no more
	// results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// ReadTime: Time used for executing the groupBy request.
	ReadTime string `json:"readTime,omitempty"`

	// TotalSize: The total number of results matching the query.
	TotalSize int64 `json:"totalSize,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "GroupByResults") 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. "GroupByResults") 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 *GroupAssetsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GroupAssetsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GroupFindingsRequest: Request message for grouping by findings.
type GroupFindingsRequest struct {
	// CompareDuration: When compare_duration is set, the GroupResult's
	// "state_change" attribute is
	// updated to indicate whether the finding had its state changed,
	// the
	// finding's state remained unchanged, or if the finding was added
	// during the
	// compare_duration period of time that precedes the read_time. This is
	// the
	// time between (read_time - compare_duration) and read_time.
	//
	// The state_change value is derived based on the presence and state of
	// the
	// finding at the two points in time. Intermediate state changes between
	// the
	// two times don't affect the result. For example, the results aren't
	// affected
	// if the finding is made inactive and then active again.
	//
	// Possible "state_change" values when compare_duration is specified:
	//
	// * "CHANGED":   indicates that the finding was present and matched the
	// given
	//                  filter at the start of compare_duration, but changed
	// its
	//                  state at read_time.
	// * "UNCHANGED": indicates that the finding was present and matched the
	// given
	//                  filter at the start of compare_duration and did not
	// change
	//                  state at read_time.
	// * "ADDED":     indicates that the finding did not match the given
	// filter or
	//                  was not present at the start of compare_duration,
	// but was
	//                  present at read_time.
	// * "REMOVED":   indicates that the finding was present and matched
	// the
	//                  filter at the start of compare_duration, but did not
	// match
	//                  the filter at read_time.
	//
	// If compare_duration is not specified, then the only possible
	// state_change
	// is "UNUSED",  which will be the state_change set for all findings
	// present
	// at read_time.
	//
	// If this field is set then `state_change` must be a specified field
	// in
	// `group_by`.
	CompareDuration string `json:"compareDuration,omitempty"`

	// Filter: Expression that defines the filter to apply across
	// findings.
	// The expression is a list of one or more restrictions combined via
	// logical
	// operators `AND` and `OR`.
	// Parentheses are supported, and `OR` has higher precedence than
	// `AND`.
	//
	// Restrictions have the form `<field> <operator> <value>` and may have
	// a `-`
	// character in front of them to indicate negation. Examples include:
	//
	//  * name
	//  * source_properties.a_property
	//  * security_marks.marks.marka
	//
	// The supported operators are:
	//
	// * `=` for all value types.
	// * `>`, `<`, `>=`, `<=` for integer values.
	// * `:`, meaning substring matching, for strings.
	//
	// The supported value types are:
	//
	// * string literals in quotes.
	// * integer literals without quotes.
	// * boolean literals `true` and `false` without quotes.
	//
	// The following field and operator combinations are supported:
	//
	// * name: `=`
	// * parent: `=`, `:`
	// * resource_name: `=`, `:`
	// * state: `=`, `:`
	// * category: `=`, `:`
	// * external_uri: `=`, `:`
	// * event_time: `=`, `>`, `<`, `>=`, `<=`
	//
	//   Usage: This should be milliseconds since epoch or an RFC3339
	// string.
	//   Examples:
	//     "event_time = \"2019-06-10T16:07:18-07:00\""
	//     "event_time = 1560208038000"
	//
	// * security_marks.marks: `=`, `:`
	// * source_properties: `=`, `:`, `>`, `<`, `>=`, `<=`
	//
	// For example, `source_properties.size = 100` is a valid filter string.
	Filter string `json:"filter,omitempty"`

	// GroupBy: Required. Expression that defines what assets fields to use
	// for grouping (including
	// `state_change`). The string value should follow SQL syntax: comma
	// separated
	// list of fields. For example: "parent,resource_name".
	//
	// The following fields are supported:
	//
	// * resource_name
	// * category
	// * state
	// * parent
	//
	// The following fields are supported when compare_duration is set:
	//
	// * state_change
	GroupBy string `json:"groupBy,omitempty"`

	// PageSize: The maximum number of results to return in a single
	// response. Default is
	// 10, minimum is 1, maximum is 1000.
	PageSize int64 `json:"pageSize,omitempty"`

	// PageToken: The value returned by the last `GroupFindingsResponse`;
	// indicates
	// that this is a continuation of a prior `GroupFindings` call, and
	// that the system should return the next page of data.
	PageToken string `json:"pageToken,omitempty"`

	// ReadTime: Time used as a reference point when filtering findings. The
	// filter is
	// limited to findings existing at the supplied time and their values
	// are
	// those at that specific time. Absence of this field will default to
	// the
	// API's version of NOW.
	ReadTime string `json:"readTime,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CompareDuration") 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. "CompareDuration") 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 *GroupFindingsRequest) MarshalJSON() ([]byte, error) {
	type NoMethod GroupFindingsRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GroupFindingsResponse: Response message for group by findings.
type GroupFindingsResponse struct {
	// GroupByResults: Group results. There exists an element for each
	// existing unique
	// combination of property/values. The element contains a count for the
	// number
	// of times those specific property/values appear.
	GroupByResults []*GroupResult `json:"groupByResults,omitempty"`

	// NextPageToken: Token to retrieve the next page of results, or empty
	// if there are no more
	// results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// ReadTime: Time used for executing the groupBy request.
	ReadTime string `json:"readTime,omitempty"`

	// TotalSize: The total number of results matching the query.
	TotalSize int64 `json:"totalSize,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "GroupByResults") 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. "GroupByResults") 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 *GroupFindingsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GroupFindingsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GroupResult: Result containing the properties and count of a groupBy
// request.
type GroupResult struct {
	// Count: Total count of resources for the given properties.
	Count int64 `json:"count,omitempty,string"`

	// Properties: Properties matching the groupBy fields in the request.
	Properties googleapi.RawMessage `json:"properties,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Count") 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. "Count") 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 *GroupResult) MarshalJSON() ([]byte, error) {
	type NoMethod GroupResult
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// IamPolicy: IAM Policy information associated with the GCP resource
// described by the
// Cloud SCC asset. This information is managed and defined by the
// GCP
// resource and cannot be modified by the user.
type IamPolicy struct {
	// PolicyBlob: The JSON representation of the Policy associated with the
	// asset.
	// See https://cloud.google.com/iam/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 *IamPolicy) MarshalJSON() ([]byte, error) {
	type NoMethod IamPolicy
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ListAssetsResponse: Response message for listing assets.
type ListAssetsResponse struct {
	// ListAssetsResults: Assets matching the list request.
	ListAssetsResults []*ListAssetsResult `json:"listAssetsResults,omitempty"`

	// NextPageToken: Token to retrieve the next page of results, or empty
	// if there are no more
	// results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// ReadTime: Time used for executing the list request.
	ReadTime string `json:"readTime,omitempty"`

	// TotalSize: The total number of assets matching the query.
	TotalSize int64 `json:"totalSize,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "ListAssetsResults")
	// 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. "ListAssetsResults") 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 *ListAssetsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListAssetsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ListAssetsResult: Result containing the Asset and its State.
type ListAssetsResult struct {
	// Asset: Asset matching the search request.
	Asset *Asset `json:"asset,omitempty"`

	// StateChange: State change of the asset between the points in time.
	//
	// Possible values:
	//   "UNUSED" - State change is unused, this is the canonical default
	// for this enum.
	//   "ADDED" - Asset was added between the points in time.
	//   "REMOVED" - Asset was removed between the points in time.
	//   "ACTIVE" - Asset was present at both point(s) in time.
	StateChange string `json:"stateChange,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 *ListAssetsResult) MarshalJSON() ([]byte, error) {
	type NoMethod ListAssetsResult
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ListFindingsResponse: Response message for listing findings.
type ListFindingsResponse struct {
	// ListFindingsResults: Findings matching the list request.
	ListFindingsResults []*ListFindingsResult `json:"listFindingsResults,omitempty"`

	// NextPageToken: Token to retrieve the next page of results, or empty
	// if there are no more
	// results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// ReadTime: Time used for executing the list request.
	ReadTime string `json:"readTime,omitempty"`

	// TotalSize: The total number of findings matching the query.
	TotalSize int64 `json:"totalSize,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "ListFindingsResults")
	// 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. "ListFindingsResults") 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 *ListFindingsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListFindingsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ListFindingsResult: Result containing the Finding and its
// StateChange.
type ListFindingsResult struct {
	// Finding: Finding matching the search request.
	Finding *Finding `json:"finding,omitempty"`

	// Resource: Output only. Resource that is associated with this finding.
	Resource *Resource `json:"resource,omitempty"`

	// StateChange: State change of the finding between the points in time.
	//
	// Possible values:
	//   "UNUSED" - State change is unused, this is the canonical default
	// for this enum.
	//   "CHANGED" - The finding has changed state in some way between the
	// points in time
	// and existed at both points.
	//   "UNCHANGED" - The finding has not changed state between the points
	// in time and
	// existed at both points.
	//   "ADDED" - The finding was created between the points in time.
	//   "REMOVED" - The finding at timestamp does not match the filter
	// specified, but it
	// did at timestamp - compare_duration.
	StateChange string `json:"stateChange,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 *ListFindingsResult) MarshalJSON() ([]byte, error) {
	type NoMethod ListFindingsResult
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ListNotificationConfigsResponse: Response message for listing
// notification configs.
type ListNotificationConfigsResponse struct {
	// NextPageToken: Token to retrieve the next page of results, or empty
	// if there are no more
	// results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// NotificationConfigs: Notification configs belonging to the requested
	// parent.
	NotificationConfigs []*NotificationConfig `json:"notificationConfigs,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 *ListNotificationConfigsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListNotificationConfigsResponse
	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)
}

// ListSourcesResponse: Response message for listing sources.
type ListSourcesResponse struct {
	// NextPageToken: Token to retrieve the next page of results, or empty
	// if there are no more
	// results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// Sources: Sources belonging to the requested parent.
	Sources []*Source `json:"sources,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 *ListSourcesResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListSourcesResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// NotificationConfig: Cloud Security Command Center (Cloud SCC)
// notification configs.
//
// A notification config is a Cloud SCC resource that contains the
// configuration
// to send notifications for create/update events of findings, assets
// and etc.
type NotificationConfig struct {
	// Description: The description of the notification config (max of 1024
	// characters).
	Description string `json:"description,omitempty"`

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

	// PubsubTopic: The PubSub topic to send notifications to. Its format
	// is
	// "projects/[project_id]/topics/[topic]".
	PubsubTopic string `json:"pubsubTopic,omitempty"`

	// ServiceAccount: Output only. The service account that needs
	// "pubsub.topics.publish"
	// permission to publish to the PubSub topic.
	ServiceAccount string `json:"serviceAccount,omitempty"`

	// StreamingConfig: The config for triggering streaming-based
	// notifications.
	StreamingConfig *StreamingConfig `json:"streamingConfig,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Description") 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. "Description") 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 *NotificationConfig) MarshalJSON() ([]byte, error) {
	type NoMethod NotificationConfig
	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)
}

// OrganizationSettings: User specified settings that are attached to
// the Cloud Security Command
// Center (Cloud SCC) organization.
type OrganizationSettings struct {
	// AssetDiscoveryConfig: The configuration used for Asset Discovery
	// runs.
	AssetDiscoveryConfig *AssetDiscoveryConfig `json:"assetDiscoveryConfig,omitempty"`

	// EnableAssetDiscovery: A flag that indicates if Asset Discovery should
	// be enabled. If the flag is
	// set to `true`, then discovery of assets will occur. If it is set to
	// `false,
	// all historical assets will remain, but discovery of future assets
	// will not
	// occur.
	EnableAssetDiscovery bool `json:"enableAssetDiscovery,omitempty"`

	// Name: The relative resource name of the settings.
	// See:
	// https://cloud.google.com/apis/design/resource_names#relative_reso
	// urce_name
	// Example:
	// "organizations/{organization_id}/organizationSettin
	// gs".
	Name string `json:"name,omitempty"`

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

	// ForceSendFields is a list of field names (e.g.
	// "AssetDiscoveryConfig") 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. "AssetDiscoveryConfig") 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 *OrganizationSettings) MarshalJSON() ([]byte, error) {
	type NoMethod OrganizationSettings
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Policy: An Identity and Access Management (IAM) policy, which
// specifies access
// controls for Google Cloud resources.
//
//
// A `Policy` is a collection of `bindings`. A `binding` binds one or
// more
// `members` to a single `role`. Members can be user accounts, service
// accounts,
// Google groups, and domains (such as G Suite). A `role` is a named
// list of
// permissions; each `role` can be an IAM predefined role or a
// user-created
// custom role.
//
// Optionally, a `binding` can specify a `condition`, which is a
// logical
// expression that allows access to a resource only if the expression
// evaluates
// to `true`. A condition can add constraints based on attributes of
// the
// request, the resource, or both.
//
// **JSON example:**
//
//     {
//       "bindings": [
//         {
//           "role": "roles/resourcemanager.organizationAdmin",
//           "members": [
//             "user:mike@example.com",
//             "group:admins@example.com",
//             "domain:google.com",
//
// "serviceAccount:my-project-id@appspot.gserviceaccount.com"
//           ]
//         },
//         {
//           "role": "roles/resourcemanager.organizationViewer",
//           "members": ["user:eve@example.com"],
//           "condition": {
//             "title": "expirable access",
//             "description": "Does not grant access after Sep 2020",
//             "expression": "request.time <
// timestamp('2020-10-01T00:00:00.000Z')",
//           }
//         }
//       ],
//       "etag": "BwWWja0YfJA=",
//       "version": 3
//     }
//
// **YAML example:**
//
//     bindings:
//     - members:
//       - user:mike@example.com
//       - group:admins@example.com
//       - domain:google.com
//       - serviceAccount:my-project-id@appspot.gserviceaccount.com
//       role: roles/resourcemanager.organizationAdmin
//     - members:
//       - user:eve@example.com
//       role: roles/resourcemanager.organizationViewer
//       condition:
//         title: expirable access
//         description: Does not grant access after Sep 2020
//         expression: request.time <
// timestamp('2020-10-01T00:00:00.000Z')
//     - etag: BwWWja0YfJA=
//     - version: 3
//
// For a description of IAM and its features, see the
// [IAM documentation](https://cloud.google.com/iam/docs/).
type Policy struct {
	// AuditConfigs: Specifies cloud audit logging configuration for this
	// policy.
	AuditConfigs []*AuditConfig `json:"auditConfigs,omitempty"`

	// Bindings: Associates a list of `members` to a `role`. Optionally, may
	// specify a
	// `condition` that determines how and when the `bindings` are applied.
	// Each
	// of the `bindings` must contain at least one member.
	Bindings []*Binding `json:"bindings,omitempty"`

	// Etag: `etag` is used for optimistic concurrency control as a way to
	// help
	// prevent simultaneous updates of a policy from overwriting each
	// other.
	// It is strongly suggested that systems make use of the `etag` in
	// the
	// read-modify-write cycle to perform policy updates in order to avoid
	// race
	// conditions: An `etag` is returned in the response to `getIamPolicy`,
	// and
	// systems are expected to put that etag in the request to
	// `setIamPolicy` to
	// ensure that their change will be applied to the same version of the
	// policy.
	//
	// **Important:** If you use IAM Conditions, you must include the `etag`
	// field
	// whenever you call `setIamPolicy`. If you omit this field, then IAM
	// allows
	// you to overwrite a version `3` policy with a version `1` policy, and
	// all of
	// the conditions in the version `3` policy are lost.
	Etag string `json:"etag,omitempty"`

	// Version: Specifies the format of the policy.
	//
	// Valid values are `0`, `1`, and `3`. Requests that specify an invalid
	// value
	// are rejected.
	//
	// Any operation that affects conditional role bindings must specify
	// version
	// `3`. This requirement applies to the following operations:
	//
	// * Getting a policy that includes a conditional role binding
	// * Adding a conditional role binding to a policy
	// * Changing a conditional role binding in a policy
	// * Removing any role binding, with or without a condition, from a
	// policy
	//   that includes conditions
	//
	// **Important:** If you use IAM Conditions, you must include the `etag`
	// field
	// whenever you call `setIamPolicy`. If you omit this field, then IAM
	// allows
	// you to overwrite a version `3` policy with a version `1` policy, and
	// all of
	// the conditions in the version `3` policy are lost.
	//
	// If a policy does not include any conditions, operations on that
	// policy may
	// specify any valid version or leave the field unset.
	Version int64 `json:"version,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "AuditConfigs") 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. "AuditConfigs") 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 *Policy) MarshalJSON() ([]byte, error) {
	type NoMethod Policy
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Resource: Information related to the Google Cloud Platform (GCP)
// resource that is
// associated with this finding.
type Resource 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"`

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

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

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

	// ProjectName: The full resource name of project that the resource
	// belongs to.
	ProjectName string `json:"projectName,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 *Resource) MarshalJSON() ([]byte, error) {
	type NoMethod Resource
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// RunAssetDiscoveryRequest: Request message for running asset discovery
// for an organization.
type RunAssetDiscoveryRequest struct {
}

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

	// ResourceName: The full resource name of the GCP 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 GCP resource. Examples include:
	// APPLICATION,
	// PROJECT, and ORGANIZATION. This is a case insensitive field defined
	// by
	// Cloud SCC 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 *SecurityCenterProperties) MarshalJSON() ([]byte, error) {
	type NoMethod SecurityCenterProperties
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SecurityMarks: User specified security marks that are attached to the
// parent Cloud Security
// Command Center (Cloud SCC) resource. Security marks are scoped within
// a Cloud
// SCC 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"`

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

	// 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)
}

// SetFindingStateRequest: Request message for updating a finding's
// state.
type SetFindingStateRequest struct {
	// StartTime: Required. The time at which the updated state takes
	// effect.
	StartTime string `json:"startTime,omitempty"`

	// State: Required. The desired 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. "StartTime") 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. "StartTime") 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 *SetFindingStateRequest) MarshalJSON() ([]byte, error) {
	type NoMethod SetFindingStateRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SetIamPolicyRequest: Request message for `SetIamPolicy` method.
type SetIamPolicyRequest struct {
	// Policy: REQUIRED: The complete policy to be applied to the
	// `resource`. The size of
	// the policy is limited to a few 10s of KB. An empty policy is a
	// valid policy but certain Cloud Platform services (such as
	// Projects)
	// might reject them.
	Policy *Policy `json:"policy,omitempty"`

	// UpdateMask: OPTIONAL: A FieldMask specifying which fields of the
	// policy to modify. Only
	// the fields in the mask will be modified. If no mask is provided,
	// the
	// following default mask is used:
	// paths: "bindings, etag"
	// This field is only used by Cloud IAM.
	UpdateMask string `json:"updateMask,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Policy") 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. "Policy") 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 *SetIamPolicyRequest) MarshalJSON() ([]byte, error) {
	type NoMethod SetIamPolicyRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Source: Cloud Security Command Center's (Cloud SCC) finding source. A
// finding source
// is an entity or a mechanism that can produce a finding. A source is
// like a
// container of findings that come from the same scanner, logger,
// monitor, and
// other tools.
type Source struct {
	// Description: The description of the source (max of 1024
	// characters).
	// Example:
	// "Web Security Scanner is a web security scanner for
	// common
	// vulnerabilities in App Engine applications. It can automatically
	// scan and detect four common vulnerabilities, including
	// cross-site-scripting
	// (XSS), Flash injection, mixed content (HTTP in HTTPS), and
	// outdated or insecure libraries."
	Description string `json:"description,omitempty"`

	// DisplayName: The source's display name.
	// A source's display name must be unique amongst its siblings, for
	// example,
	// two sources with the same parent can't share the same display
	// name.
	// The display name must have a length between 1 and 64
	// characters
	// (inclusive).
	DisplayName string `json:"displayName,omitempty"`

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

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

	// ForceSendFields is a list of field names (e.g. "Description") 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. "Description") 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 *Source) MarshalJSON() ([]byte, error) {
	type NoMethod Source
	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)
}

// StreamingConfig: The config for streaming-based notifications, which
// send each event as soon
// as it is detected.
type StreamingConfig struct {
	// Filter: Expression that defines the filter to apply across
	// create/update events
	// of assets or findings as specified by the event type. The expression
	// is a
	// list of zero or more restrictions combined via logical operators
	// `AND`
	// and `OR`. Parentheses are supported, and `OR` has higher precedence
	// than
	// `AND`.
	//
	// Restrictions have the form `<field> <operator> <value>` and may have
	// a
	// `-` character in front of them to indicate negation. The fields map
	// to
	// those defined in the corresponding resource.
	//
	// The supported operators are:
	//
	// * `=` for all value types.
	// * `>`, `<`, `>=`, `<=` for integer values.
	// * `:`, meaning substring matching, for strings.
	//
	// The supported value types are:
	//
	// * string literals in quotes.
	// * integer literals without quotes.
	// * boolean literals `true` and `false` without quotes.
	Filter string `json:"filter,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Filter") 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. "Filter") 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 *StreamingConfig) MarshalJSON() ([]byte, error) {
	type NoMethod StreamingConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TestIamPermissionsRequest: Request message for `TestIamPermissions`
// method.
type TestIamPermissionsRequest struct {
	// Permissions: The set of permissions to check for the `resource`.
	// Permissions with
	// wildcards (such as '*' or 'storage.*') are not allowed. For
	// more
	// information see
	// [IAM
	// Overview](https://cloud.google.com/iam/docs/overview#permissions).
	Permissions []string `json:"permissions,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Permissions") 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. "Permissions") 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 *TestIamPermissionsRequest) MarshalJSON() ([]byte, error) {
	type NoMethod TestIamPermissionsRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TestIamPermissionsResponse: Response message for `TestIamPermissions`
// method.
type TestIamPermissionsResponse struct {
	// Permissions: A subset of `TestPermissionsRequest.permissions` that
	// the caller is
	// allowed.
	Permissions []string `json:"permissions,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Permissions") 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. "Permissions") 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 *TestIamPermissionsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod TestIamPermissionsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// method id "securitycenter.organizations.getOrganizationSettings":

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

// GetOrganizationSettings: Gets the settings for an organization.
func (r *OrganizationsService) GetOrganizationSettings(name string) *OrganizationsGetOrganizationSettingsCall {
	c := &OrganizationsGetOrganizationSettingsCall{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 *OrganizationsGetOrganizationSettingsCall) Fields(s ...googleapi.Field) *OrganizationsGetOrganizationSettingsCall {
	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 *OrganizationsGetOrganizationSettingsCall) IfNoneMatch(entityTag string) *OrganizationsGetOrganizationSettingsCall {
	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 *OrganizationsGetOrganizationSettingsCall) Context(ctx context.Context) *OrganizationsGetOrganizationSettingsCall {
	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 *OrganizationsGetOrganizationSettingsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsGetOrganizationSettingsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200315")
	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, "v1/{+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.getOrganizationSettings" call.
// Exactly one of *OrganizationSettings or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *OrganizationSettings.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 *OrganizationsGetOrganizationSettingsCall) Do(opts ...googleapi.CallOption) (*OrganizationSettings, 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 := &OrganizationSettings{
		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 settings for an organization.",
	//   "flatPath": "v1/organizations/{organizationsId}/organizationSettings",
	//   "httpMethod": "GET",
	//   "id": "securitycenter.organizations.getOrganizationSettings",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Name of the organization to get organization settings for. Its format is\n\"organizations/[organization_id]/organizationSettings\".",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/organizationSettings$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "OrganizationSettings"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "securitycenter.organizations.updateOrganizationSettings":

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

// UpdateOrganizationSettings: Updates an organization's settings.
func (r *OrganizationsService) UpdateOrganizationSettings(name string, organizationsettings *OrganizationSettings) *OrganizationsUpdateOrganizationSettingsCall {
	c := &OrganizationsUpdateOrganizationSettingsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.organizationsettings = organizationsettings
	return c
}

// UpdateMask sets the optional parameter "updateMask": The FieldMask to
// use when updating the settings resource.
//
//  If empty all mutable fields will be updated.
func (c *OrganizationsUpdateOrganizationSettingsCall) UpdateMask(updateMask string) *OrganizationsUpdateOrganizationSettingsCall {
	c.urlParams_.Set("updateMask", updateMask)
	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 *OrganizationsUpdateOrganizationSettingsCall) Fields(s ...googleapi.Field) *OrganizationsUpdateOrganizationSettingsCall {
	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 *OrganizationsUpdateOrganizationSettingsCall) Context(ctx context.Context) *OrganizationsUpdateOrganizationSettingsCall {
	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 *OrganizationsUpdateOrganizationSettingsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsUpdateOrganizationSettingsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200315")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.organizationsettings)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PATCH", 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.updateOrganizationSettings" call.
// Exactly one of *OrganizationSettings or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *OrganizationSettings.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 *OrganizationsUpdateOrganizationSettingsCall) Do(opts ...googleapi.CallOption) (*OrganizationSettings, 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 := &OrganizationSettings{
		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": "Updates an organization's settings.",
	//   "flatPath": "v1/organizations/{organizationsId}/organizationSettings",
	//   "httpMethod": "PATCH",
	//   "id": "securitycenter.organizations.updateOrganizationSettings",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The relative resource name of the settings. See:\nhttps://cloud.google.com/apis/design/resource_names#relative_resource_name\nExample:\n\"organizations/{organization_id}/organizationSettings\".",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/organizationSettings$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "updateMask": {
	//       "description": "The FieldMask to use when updating the settings resource.\n\n If empty all mutable fields will be updated.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "request": {
	//     "$ref": "OrganizationSettings"
	//   },
	//   "response": {
	//     "$ref": "OrganizationSettings"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "securitycenter.organizations.assets.group":

type OrganizationsAssetsGroupCall struct {
	s                  *Service
	parent             string
	groupassetsrequest *GroupAssetsRequest
	urlParams_         gensupport.URLParams
	ctx_               context.Context
	header_            http.Header
}

// Group: Filters an organization's assets and  groups them by their
// specified
// properties.
func (r *OrganizationsAssetsService) Group(parent string, groupassetsrequest *GroupAssetsRequest) *OrganizationsAssetsGroupCall {
	c := &OrganizationsAssetsGroupCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.groupassetsrequest = groupassetsrequest
	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 *OrganizationsAssetsGroupCall) Fields(s ...googleapi.Field) *OrganizationsAssetsGroupCall {
	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 *OrganizationsAssetsGroupCall) Context(ctx context.Context) *OrganizationsAssetsGroupCall {
	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 *OrganizationsAssetsGroupCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsAssetsGroupCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200315")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.groupassetsrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/assets:group")
	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{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "securitycenter.organizations.assets.group" call.
// Exactly one of *GroupAssetsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GroupAssetsResponse.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 *OrganizationsAssetsGroupCall) Do(opts ...googleapi.CallOption) (*GroupAssetsResponse, 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 := &GroupAssetsResponse{
		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": "Filters an organization's assets and  groups them by their specified\nproperties.",
	//   "flatPath": "v1/organizations/{organizationsId}/assets:group",
	//   "httpMethod": "POST",
	//   "id": "securitycenter.organizations.assets.group",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. Name of the organization to groupBy. Its format is\n\"organizations/[organization_id]\".",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/assets:group",
	//   "request": {
	//     "$ref": "GroupAssetsRequest"
	//   },
	//   "response": {
	//     "$ref": "GroupAssetsResponse"
	//   },
	//   "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 *OrganizationsAssetsGroupCall) Pages(ctx context.Context, f func(*GroupAssetsResponse) error) error {
	c.ctx_ = ctx
	defer func(pt string) { c.groupassetsrequest.PageToken = pt }(c.groupassetsrequest.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.groupassetsrequest.PageToken = x.NextPageToken
	}
}

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

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

// List: Lists an organization's assets.
func (r *OrganizationsAssetsService) List(parent string) *OrganizationsAssetsListCall {
	c := &OrganizationsAssetsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// CompareDuration sets the optional parameter "compareDuration": When
// compare_duration is set, the ListAssetsResult's
// "state_change"
// attribute is updated to indicate whether the asset was added,
// removed, or
// remained present during the compare_duration period of time that
// precedes
// the read_time. This is the time between (read_time -
// compare_duration) and
// read_time.
//
// The state_change value is derived based on the presence of the asset
// at the
// two points in time. Intermediate state changes between the two times
// don't
// affect the result. For example, the results aren't affected if the
// asset is
// removed and re-created again.
//
// Possible "state_change" values when compare_duration is specified:
//
// * "ADDED":   indicates that the asset was not present at the start
// of
//                compare_duration, but present at read_time.
// * "REMOVED": indicates that the asset was present at the start of
//                compare_duration, but not present at read_time.
// * "ACTIVE":  indicates that the asset was present at both the
//                start and the end of the time period defined by
//                compare_duration and read_time.
//
// If compare_duration is not specified, then the only possible
// state_change
// is "UNUSED",  which will be the state_change set for all assets
// present at
// read_time.
func (c *OrganizationsAssetsListCall) CompareDuration(compareDuration string) *OrganizationsAssetsListCall {
	c.urlParams_.Set("compareDuration", compareDuration)
	return c
}

// FieldMask sets the optional parameter "fieldMask": A field mask to
// specify the ListAssetsResult fields to be listed in the
// response.
// An empty field mask will list all fields.
func (c *OrganizationsAssetsListCall) FieldMask(fieldMask string) *OrganizationsAssetsListCall {
	c.urlParams_.Set("fieldMask", fieldMask)
	return c
}

// Filter sets the optional parameter "filter": Expression that defines
// the filter to apply across assets.
// The expression is a list of zero or more restrictions combined via
// logical
// operators `AND` and `OR`.
// Parentheses are supported, and `OR` has higher precedence than
// `AND`.
//
// Restrictions have the form `<field> <operator> <value>` and may have
// a `-`
// character in front of them to indicate negation. The fields map to
// those
// defined in the Asset resource. Examples include:
//
// * name
// * security_center_properties.resource_name
// * resource_properties.a_property
// * security_marks.marks.marka
//
// The supported operators are:
//
// * `=` for all value types.
// * `>`, `<`, `>=`, `<=` for integer values.
// * `:`, meaning substring matching, for strings.
//
// The supported value types are:
//
// * string literals in quotes.
// * integer literals without quotes.
// * boolean literals `true` and `false` without quotes.
//
// The following are the allowed field and operator combinations:
//
// * name: `=`
// * update_time: `=`, `>`, `<`, `>=`, `<=`
//
//   Usage: This should be milliseconds since epoch or an RFC3339
// string.
//   Examples:
//     "update_time = \"2019-06-10T16:07:18-07:00\""
//     "update_time = 1560208038000"
//
// * create_time: `=`, `>`, `<`, `>=`, `<=`
//
//   Usage: This should be milliseconds since epoch or an RFC3339
// string.
//   Examples:
//     "create_time = \"2019-06-10T16:07:18-07:00\""
//     "create_time = 1560208038000"
//
// * iam_policy.policy_blob: `=`, `:`
// * resource_properties: `=`, `:`, `>`, `<`, `>=`, `<=`
// * security_marks.marks: `=`, `:`
// * security_center_properties.resource_name: `=`, `:`
// * security_center_properties.resource_display_name: `=`, `:`
// * security_center_properties.resource_type: `=`, `:`
// * security_center_properties.resource_parent: `=`, `:`
// * security_center_properties.resource_parent_display_name: `=`, `:`
// * security_center_properties.resource_project: `=`, `:`
// * security_center_properties.resource_project_display_name: `=`,
// `:`
// * security_center_properties.resource_owners: `=`, `:`
//
// For example, `resource_properties.size = 100` is a valid filter
// string.
func (c *OrganizationsAssetsListCall) Filter(filter string) *OrganizationsAssetsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// OrderBy sets the optional parameter "orderBy": Expression that
// defines what fields and order to use for sorting. The
// string value should follow SQL syntax: comma separated list of
// fields. For
// example: "name,resource_properties.a_property". The default sorting
// order
// is ascending. To specify descending order for a field, a suffix "
// desc"
// should be appended to the field name. For example:
// "name
// desc,resource_properties.a_property". Redundant space characters in
// the
// syntax are insignificant. "name desc,resource_properties.a_property"
// and "
// name     desc  ,   resource_properties.a_property  " are
// equivalent.
//
// The following fields are
// supported:
// name
// update_time
// resource_properties
// security_marks.marks
// s
// ecurity_center_properties.resource_name
// security_center_properties.res
// ource_display_name
// security_center_properties.resource_parent
// security
// _center_properties.resource_parent_display_name
// security_center_proper
// ties.resource_project
// security_center_properties.resource_project_disp
// lay_name
// security_center_properties.resource_type
func (c *OrganizationsAssetsListCall) OrderBy(orderBy string) *OrganizationsAssetsListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number
// of results to return in a single response. Default is
// 10, minimum is 1, maximum is 1000.
func (c *OrganizationsAssetsListCall) PageSize(pageSize int64) *OrganizationsAssetsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The value returned
// by the last `ListAssetsResponse`; indicates
// that this is a continuation of a prior `ListAssets` call, and
// that the system should return the next page of data.
func (c *OrganizationsAssetsListCall) PageToken(pageToken string) *OrganizationsAssetsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// ReadTime sets the optional parameter "readTime": Time used as a
// reference point when filtering assets. The filter is limited
// to assets existing at the supplied time and their values are those at
// that
// specific time. Absence of this field will default to the API's
// version of
// NOW.
func (c *OrganizationsAssetsListCall) ReadTime(readTime string) *OrganizationsAssetsListCall {
	c.urlParams_.Set("readTime", readTime)
	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 *OrganizationsAssetsListCall) Fields(s ...googleapi.Field) *OrganizationsAssetsListCall {
	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 *OrganizationsAssetsListCall) IfNoneMatch(entityTag string) *OrganizationsAssetsListCall {
	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 *OrganizationsAssetsListCall) Context(ctx context.Context) *OrganizationsAssetsListCall {
	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 *OrganizationsAssetsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsAssetsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200315")
	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, "v1/{+parent}/assets")
	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{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "securitycenter.organizations.assets.list" call.
// Exactly one of *ListAssetsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListAssetsResponse.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 *OrganizationsAssetsListCall) Do(opts ...googleapi.CallOption) (*ListAssetsResponse, 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 := &ListAssetsResponse{
		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 an organization's assets.",
	//   "flatPath": "v1/organizations/{organizationsId}/assets",
	//   "httpMethod": "GET",
	//   "id": "securitycenter.organizations.assets.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "compareDuration": {
	//       "description": "When compare_duration is set, the ListAssetsResult's \"state_change\"\nattribute is updated to indicate whether the asset was added, removed, or\nremained present during the compare_duration period of time that precedes\nthe read_time. This is the time between (read_time - compare_duration) and\nread_time.\n\nThe state_change value is derived based on the presence of the asset at the\ntwo points in time. Intermediate state changes between the two times don't\naffect the result. For example, the results aren't affected if the asset is\nremoved and re-created again.\n\nPossible \"state_change\" values when compare_duration is specified:\n\n* \"ADDED\":   indicates that the asset was not present at the start of\n               compare_duration, but present at read_time.\n* \"REMOVED\": indicates that the asset was present at the start of\n               compare_duration, but not present at read_time.\n* \"ACTIVE\":  indicates that the asset was present at both the\n               start and the end of the time period defined by\n               compare_duration and read_time.\n\nIf compare_duration is not specified, then the only possible state_change\nis \"UNUSED\",  which will be the state_change set for all assets present at\nread_time.",
	//       "format": "google-duration",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "fieldMask": {
	//       "description": "Optional. A field mask to specify the ListAssetsResult fields to be listed in the\nresponse.\nAn empty field mask will list all fields.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "filter": {
	//       "description": "Expression that defines the filter to apply across assets.\nThe expression is a list of zero or more restrictions combined via logical\noperators `AND` and `OR`.\nParentheses are supported, and `OR` has higher precedence than `AND`.\n\nRestrictions have the form `\u003cfield\u003e \u003coperator\u003e \u003cvalue\u003e` and may have a `-`\ncharacter in front of them to indicate negation. The fields map to those\ndefined in the Asset resource. Examples include:\n\n* name\n* security_center_properties.resource_name\n* resource_properties.a_property\n* security_marks.marks.marka\n\nThe supported operators are:\n\n* `=` for all value types.\n* `\u003e`, `\u003c`, `\u003e=`, `\u003c=` for integer values.\n* `:`, meaning substring matching, for strings.\n\nThe supported value types are:\n\n* string literals in quotes.\n* integer literals without quotes.\n* boolean literals `true` and `false` without quotes.\n\nThe following are the allowed field and operator combinations:\n\n* name: `=`\n* update_time: `=`, `\u003e`, `\u003c`, `\u003e=`, `\u003c=`\n\n  Usage: This should be milliseconds since epoch or an RFC3339 string.\n  Examples:\n    \"update_time = \\\"2019-06-10T16:07:18-07:00\\\"\"\n    \"update_time = 1560208038000\"\n\n* create_time: `=`, `\u003e`, `\u003c`, `\u003e=`, `\u003c=`\n\n  Usage: This should be milliseconds since epoch or an RFC3339 string.\n  Examples:\n    \"create_time = \\\"2019-06-10T16:07:18-07:00\\\"\"\n    \"create_time = 1560208038000\"\n\n* iam_policy.policy_blob: `=`, `:`\n* resource_properties: `=`, `:`, `\u003e`, `\u003c`, `\u003e=`, `\u003c=`\n* security_marks.marks: `=`, `:`\n* security_center_properties.resource_name: `=`, `:`\n* security_center_properties.resource_display_name: `=`, `:`\n* security_center_properties.resource_type: `=`, `:`\n* security_center_properties.resource_parent: `=`, `:`\n* security_center_properties.resource_parent_display_name: `=`, `:`\n* security_center_properties.resource_project: `=`, `:`\n* security_center_properties.resource_project_display_name: `=`, `:`\n* security_center_properties.resource_owners: `=`, `:`\n\nFor example, `resource_properties.size = 100` is a valid filter string.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "orderBy": {
	//       "description": "Expression that defines what fields and order to use for sorting. The\nstring value should follow SQL syntax: comma separated list of fields. For\nexample: \"name,resource_properties.a_property\". The default sorting order\nis ascending. To specify descending order for a field, a suffix \" desc\"\nshould be appended to the field name. For example: \"name\ndesc,resource_properties.a_property\". Redundant space characters in the\nsyntax are insignificant. \"name desc,resource_properties.a_property\" and \"\nname     desc  ,   resource_properties.a_property  \" are equivalent.\n\nThe following fields are supported:\nname\nupdate_time\nresource_properties\nsecurity_marks.marks\nsecurity_center_properties.resource_name\nsecurity_center_properties.resource_display_name\nsecurity_center_properties.resource_parent\nsecurity_center_properties.resource_parent_display_name\nsecurity_center_properties.resource_project\nsecurity_center_properties.resource_project_display_name\nsecurity_center_properties.resource_type",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "The maximum number of results to return in a single response. Default is\n10, minimum is 1, maximum is 1000.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The value returned by the last `ListAssetsResponse`; indicates\nthat this is a continuation of a prior `ListAssets` call, and\nthat the system should return the next page of data.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. Name of the organization assets should belong to. Its format is\n\"organizations/[organization_id]\".",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "readTime": {
	//       "description": "Time used as a reference point when filtering assets. The filter is limited\nto assets existing at the supplied time and their values are those at that\nspecific time. Absence of this field will default to the API's version of\nNOW.",
	//       "format": "google-datetime",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/assets",
	//   "response": {
	//     "$ref": "ListAssetsResponse"
	//   },
	//   "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 *OrganizationsAssetsListCall) Pages(ctx context.Context, f func(*ListAssetsResponse) 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)
	}
}

// method id "securitycenter.organizations.assets.runDiscovery":

type OrganizationsAssetsRunDiscoveryCall struct {
	s                        *Service
	parent                   string
	runassetdiscoveryrequest *RunAssetDiscoveryRequest
	urlParams_               gensupport.URLParams
	ctx_                     context.Context
	header_                  http.Header
}

// RunDiscovery: Runs asset discovery. The discovery is tracked with a
// long-running
// operation.
//
// This API can only be called with limited frequency for an
// organization. If
// it is called too frequently the caller will receive a
// TOO_MANY_REQUESTS
// error.
func (r *OrganizationsAssetsService) RunDiscovery(parent string, runassetdiscoveryrequest *RunAssetDiscoveryRequest) *OrganizationsAssetsRunDiscoveryCall {
	c := &OrganizationsAssetsRunDiscoveryCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.runassetdiscoveryrequest = runassetdiscoveryrequest
	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 *OrganizationsAssetsRunDiscoveryCall) Fields(s ...googleapi.Field) *OrganizationsAssetsRunDiscoveryCall {
	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 *OrganizationsAssetsRunDiscoveryCall) Context(ctx context.Context) *OrganizationsAssetsRunDiscoveryCall {
	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 *OrganizationsAssetsRunDiscoveryCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsAssetsRunDiscoveryCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200315")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.runassetdiscoveryrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/assets:runDiscovery")
	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{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "securitycenter.organizations.assets.runDiscovery" 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 *OrganizationsAssetsRunDiscoveryCall) 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": "Runs asset discovery. The discovery is tracked with a long-running\noperation.\n\nThis API can only be called with limited frequency for an organization. If\nit is called too frequently the caller will receive a TOO_MANY_REQUESTS\nerror.",
	//   "flatPath": "v1/organizations/{organizationsId}/assets:runDiscovery",
	//   "httpMethod": "POST",
	//   "id": "securitycenter.organizations.assets.runDiscovery",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. Name of the organization to run asset discovery for. Its format is\n\"organizations/[organization_id]\".",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/assets:runDiscovery",
	//   "request": {
	//     "$ref": "RunAssetDiscoveryRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "securitycenter.organizations.assets.updateSecurityMarks":

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

// UpdateSecurityMarks: Updates security marks.
func (r *OrganizationsAssetsService) UpdateSecurityMarks(name string, securitymarks *SecurityMarks) *OrganizationsAssetsUpdateSecurityMarksCall {
	c := &OrganizationsAssetsUpdateSecurityMarksCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.securitymarks = securitymarks
	return c
}

// StartTime sets the optional parameter "startTime": The time at which
// the updated SecurityMarks take effect.
// If not set uses current server time.  Updates will be applied to
// the
// SecurityMarks that are active immediately preceding this time.
func (c *OrganizationsAssetsUpdateSecurityMarksCall) StartTime(startTime string) *OrganizationsAssetsUpdateSecurityMarksCall {
	c.urlParams_.Set("startTime", startTime)
	return c
}

// UpdateMask sets the optional parameter "updateMask": The FieldMask to
// use when updating the security marks resource.
//
// The field mask must not contain duplicate fields.
// If empty or set to "marks", all marks will be replaced.
// Individual
// marks can be updated using "marks.<mark_key>".
func (c *OrganizationsAssetsUpdateSecurityMarksCall) UpdateMask(updateMask string) *OrganizationsAssetsUpdateSecurityMarksCall {
	c.urlParams_.Set("updateMask", updateMask)
	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 *OrganizationsAssetsUpdateSecurityMarksCall) Fields(s ...googleapi.Field) *OrganizationsAssetsUpdateSecurityMarksCall {
	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 *OrganizationsAssetsUpdateSecurityMarksCall) Context(ctx context.Context) *OrganizationsAssetsUpdateSecurityMarksCall {
	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 *OrganizationsAssetsUpdateSecurityMarksCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsAssetsUpdateSecurityMarksCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200315")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.securitymarks)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PATCH", 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.assets.updateSecurityMarks" call.
// Exactly one of *SecurityMarks or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *SecurityMarks.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 *OrganizationsAssetsUpdateSecurityMarksCall) Do(opts ...googleapi.CallOption) (*SecurityMarks, 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 := &SecurityMarks{
		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": "Updates security marks.",
	//   "flatPath": "v1/organizations/{organizationsId}/assets/{assetsId}/securityMarks",
	//   "httpMethod": "PATCH",
	//   "id": "securitycenter.organizations.assets.updateSecurityMarks",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The relative resource name of the SecurityMarks. See:\nhttps://cloud.google.com/apis/design/resource_names#relative_resource_name\nExamples:\n\"organizations/{organization_id}/assets/{asset_id}/securityMarks\"\n\"organizations/{organization_id}/sources/{source_id}/findings/{finding_id}/securityMarks\".",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/assets/[^/]+/securityMarks$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "startTime": {
	//       "description": "The time at which the updated SecurityMarks take effect.\nIf not set uses current server time.  Updates will be applied to the\nSecurityMarks that are active immediately preceding this time.",
	//       "format": "google-datetime",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "updateMask": {
	//       "description": "The FieldMask to use when updating the security marks resource.\n\nThe field mask must not contain duplicate fields.\nIf empty or set to \"marks\", all marks will be replaced.  Individual\nmarks can be updated using \"marks.\u003cmark_key\u003e\".",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "request": {
	//     "$ref": "SecurityMarks"
	//   },
	//   "response": {
	//     "$ref": "SecurityMarks"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "securitycenter.organizations.notificationConfigs.create":

type OrganizationsNotificationConfigsCreateCall struct {
	s                  *Service
	parent             string
	notificationconfig *NotificationConfig
	urlParams_         gensupport.URLParams
	ctx_               context.Context
	header_            http.Header
}

// Create: Creates a notification config.
func (r *OrganizationsNotificationConfigsService) Create(parent string, notificationconfig *NotificationConfig) *OrganizationsNotificationConfigsCreateCall {
	c := &OrganizationsNotificationConfigsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.notificationconfig = notificationconfig
	return c
}

// ConfigId sets the optional parameter "configId": Required.
// Unique identifier provided by the client within the parent scope.
// It must be between 1 and 128 characters, and contains
// alphanumeric
// characters, underscores or hyphens only.
func (c *OrganizationsNotificationConfigsCreateCall) ConfigId(configId string) *OrganizationsNotificationConfigsCreateCall {
	c.urlParams_.Set("configId", configId)
	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 *OrganizationsNotificationConfigsCreateCall) Fields(s ...googleapi.Field) *OrganizationsNotificationConfigsCreateCall {
	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 *OrganizationsNotificationConfigsCreateCall) Context(ctx context.Context) *OrganizationsNotificationConfigsCreateCall {
	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 *OrganizationsNotificationConfigsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsNotificationConfigsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200315")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.notificationconfig)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/notificationConfigs")
	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{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "securitycenter.organizations.notificationConfigs.create" call.
// Exactly one of *NotificationConfig or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *NotificationConfig.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 *OrganizationsNotificationConfigsCreateCall) Do(opts ...googleapi.CallOption) (*NotificationConfig, 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 := &NotificationConfig{
		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": "Creates a notification config.",
	//   "flatPath": "v1/organizations/{organizationsId}/notificationConfigs",
	//   "httpMethod": "POST",
	//   "id": "securitycenter.organizations.notificationConfigs.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "configId": {
	//       "description": "Required.\nUnique identifier provided by the client within the parent scope.\nIt must be between 1 and 128 characters, and contains alphanumeric\ncharacters, underscores or hyphens only.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. Resource name of the new notification config's parent. Its format is\n\"organizations/[organization_id]\".",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/notificationConfigs",
	//   "request": {
	//     "$ref": "NotificationConfig"
	//   },
	//   "response": {
	//     "$ref": "NotificationConfig"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

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

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

// Delete: Deletes a notification config.
func (r *OrganizationsNotificationConfigsService) Delete(name string) *OrganizationsNotificationConfigsDeleteCall {
	c := &OrganizationsNotificationConfigsDeleteCall{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 *OrganizationsNotificationConfigsDeleteCall) Fields(s ...googleapi.Field) *OrganizationsNotificationConfigsDeleteCall {
	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 *OrganizationsNotificationConfigsDeleteCall) Context(ctx context.Context) *OrganizationsNotificationConfigsDeleteCall {
	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 *OrganizationsNotificationConfigsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsNotificationConfigsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200315")
	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, "v1/{+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.notificationConfigs.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 *OrganizationsNotificationConfigsDeleteCall) 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 notification config.",
	//   "flatPath": "v1/organizations/{organizationsId}/notificationConfigs/{notificationConfigsId}",
	//   "httpMethod": "DELETE",
	//   "id": "securitycenter.organizations.notificationConfigs.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Name of the notification config to delete. Its format is\n\"organizations/[organization_id]/notificationConfigs/[config_id]\".",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/notificationConfigs/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "Empty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

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

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

// Get: Gets a notification config.
func (r *OrganizationsNotificationConfigsService) Get(name string) *OrganizationsNotificationConfigsGetCall {
	c := &OrganizationsNotificationConfigsGetCall{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 *OrganizationsNotificationConfigsGetCall) Fields(s ...googleapi.Field) *OrganizationsNotificationConfigsGetCall {
	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 *OrganizationsNotificationConfigsGetCall) IfNoneMatch(entityTag string) *OrganizationsNotificationConfigsGetCall {
	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 *OrganizationsNotificationConfigsGetCall) Context(ctx context.Context) *OrganizationsNotificationConfigsGetCall {
	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 *OrganizationsNotificationConfigsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsNotificationConfigsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200315")
	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, "v1/{+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.notificationConfigs.get" call.
// Exactly one of *NotificationConfig or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *NotificationConfig.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 *OrganizationsNotificationConfigsGetCall) Do(opts ...googleapi.CallOption) (*NotificationConfig, 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 := &NotificationConfig{
		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 a notification config.",
	//   "flatPath": "v1/organizations/{organizationsId}/notificationConfigs/{notificationConfigsId}",
	//   "httpMethod": "GET",
	//   "id": "securitycenter.organizations.notificationConfigs.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Name of the notification config to get. Its format is\n\"organizations/[organization_id]/notificationConfigs/[config_id]\".",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/notificationConfigs/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "NotificationConfig"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

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

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

// List: Lists notification configs.
func (r *OrganizationsNotificationConfigsService) List(parent string) *OrganizationsNotificationConfigsListCall {
	c := &OrganizationsNotificationConfigsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number
// of results to return in a single response. Default is
// 10, minimum is 1, maximum is 1000.
func (c *OrganizationsNotificationConfigsListCall) PageSize(pageSize int64) *OrganizationsNotificationConfigsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The value returned
// by the last `ListNotificationConfigsResponse`; indicates
// that this is a continuation of a prior `ListNotificationConfigs`
// call, and
// that the system should return the next page of data.
func (c *OrganizationsNotificationConfigsListCall) PageToken(pageToken string) *OrganizationsNotificationConfigsListCall {
	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 *OrganizationsNotificationConfigsListCall) Fields(s ...googleapi.Field) *OrganizationsNotificationConfigsListCall {
	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 *OrganizationsNotificationConfigsListCall) IfNoneMatch(entityTag string) *OrganizationsNotificationConfigsListCall {
	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 *OrganizationsNotificationConfigsListCall) Context(ctx context.Context) *OrganizationsNotificationConfigsListCall {
	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 *OrganizationsNotificationConfigsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsNotificationConfigsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200315")
	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, "v1/{+parent}/notificationConfigs")
	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{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "securitycenter.organizations.notificationConfigs.list" call.
// Exactly one of *ListNotificationConfigsResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *ListNotificationConfigsResponse.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 *OrganizationsNotificationConfigsListCall) Do(opts ...googleapi.CallOption) (*ListNotificationConfigsResponse, 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 := &ListNotificationConfigsResponse{
		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 notification configs.",
	//   "flatPath": "v1/organizations/{organizationsId}/notificationConfigs",
	//   "httpMethod": "GET",
	//   "id": "securitycenter.organizations.notificationConfigs.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "pageSize": {
	//       "description": "The maximum number of results to return in a single response. Default is\n10, minimum is 1, maximum is 1000.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The value returned by the last `ListNotificationConfigsResponse`; indicates\nthat this is a continuation of a prior `ListNotificationConfigs` call, and\nthat the system should return the next page of data.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. Name of the organization to list notification configs.\nIts format is \"organizations/[organization_id]\".",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/notificationConfigs",
	//   "response": {
	//     "$ref": "ListNotificationConfigsResponse"
	//   },
	//   "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 *OrganizationsNotificationConfigsListCall) Pages(ctx context.Context, f func(*ListNotificationConfigsResponse) 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)
	}
}

// method id "securitycenter.organizations.notificationConfigs.patch":

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

// Patch:
// Updates a notification config.
func (r *OrganizationsNotificationConfigsService) Patch(name string, notificationconfig *NotificationConfig) *OrganizationsNotificationConfigsPatchCall {
	c := &OrganizationsNotificationConfigsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.notificationconfig = notificationconfig
	return c
}

// UpdateMask sets the optional parameter "updateMask": The FieldMask to
// use when updating the notification config.
//
// If empty all mutable fields will be updated.
func (c *OrganizationsNotificationConfigsPatchCall) UpdateMask(updateMask string) *OrganizationsNotificationConfigsPatchCall {
	c.urlParams_.Set("updateMask", updateMask)
	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 *OrganizationsNotificationConfigsPatchCall) Fields(s ...googleapi.Field) *OrganizationsNotificationConfigsPatchCall {
	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 *OrganizationsNotificationConfigsPatchCall) Context(ctx context.Context) *OrganizationsNotificationConfigsPatchCall {
	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 *OrganizationsNotificationConfigsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsNotificationConfigsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200315")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.notificationconfig)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PATCH", 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.notificationConfigs.patch" call.
// Exactly one of *NotificationConfig or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *NotificationConfig.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 *OrganizationsNotificationConfigsPatchCall) Do(opts ...googleapi.CallOption) (*NotificationConfig, 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 := &NotificationConfig{
		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": "\nUpdates a notification config.",
	//   "flatPath": "v1/organizations/{organizationsId}/notificationConfigs/{notificationConfigsId}",
	//   "httpMethod": "PATCH",
	//   "id": "securitycenter.organizations.notificationConfigs.patch",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The relative resource name of this notification config. See:\nhttps://cloud.google.com/apis/design/resource_names#relative_resource_name\nExample:\n\"organizations/{organization_id}/notificationConfigs/notify_public_bucket\".",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/notificationConfigs/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "updateMask": {
	//       "description": "The FieldMask to use when updating the notification config.\n\nIf empty all mutable fields will be updated.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "request": {
	//     "$ref": "NotificationConfig"
	//   },
	//   "response": {
	//     "$ref": "NotificationConfig"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// 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/20200315")
	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, "v1/{+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": "v1/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": "v1/{+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/20200315")
	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, "v1/{+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": "v1/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": "v1/{+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/20200315")
	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, "v1/{+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": "v1/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": "v1/{+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/20200315")
	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, "v1/{+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": "v1/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": "v1/{+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)
	}
}

// method id "securitycenter.organizations.sources.create":

type OrganizationsSourcesCreateCall struct {
	s          *Service
	parent     string
	source     *Source
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Create: Creates a source.
func (r *OrganizationsSourcesService) Create(parent string, source *Source) *OrganizationsSourcesCreateCall {
	c := &OrganizationsSourcesCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.source = source
	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 *OrganizationsSourcesCreateCall) Fields(s ...googleapi.Field) *OrganizationsSourcesCreateCall {
	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 *OrganizationsSourcesCreateCall) Context(ctx context.Context) *OrganizationsSourcesCreateCall {
	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 *OrganizationsSourcesCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsSourcesCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200315")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.source)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/sources")
	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{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "securitycenter.organizations.sources.create" call.
// Exactly one of *Source or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Source.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 *OrganizationsSourcesCreateCall) Do(opts ...googleapi.CallOption) (*Source, 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 := &Source{
		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": "Creates a source.",
	//   "flatPath": "v1/organizations/{organizationsId}/sources",
	//   "httpMethod": "POST",
	//   "id": "securitycenter.organizations.sources.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. Resource name of the new source's parent. Its format should be\n\"organizations/[organization_id]\".",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/sources",
	//   "request": {
	//     "$ref": "Source"
	//   },
	//   "response": {
	//     "$ref": "Source"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

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

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

// Get: Gets a source.
func (r *OrganizationsSourcesService) Get(name string) *OrganizationsSourcesGetCall {
	c := &OrganizationsSourcesGetCall{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 *OrganizationsSourcesGetCall) Fields(s ...googleapi.Field) *OrganizationsSourcesGetCall {
	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 *OrganizationsSourcesGetCall) IfNoneMatch(entityTag string) *OrganizationsSourcesGetCall {
	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 *OrganizationsSourcesGetCall) Context(ctx context.Context) *OrganizationsSourcesGetCall {
	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 *OrganizationsSourcesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsSourcesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200315")
	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, "v1/{+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.sources.get" call.
// Exactly one of *Source or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Source.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 *OrganizationsSourcesGetCall) Do(opts ...googleapi.CallOption) (*Source, 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 := &Source{
		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 a source.",
	//   "flatPath": "v1/organizations/{organizationsId}/sources/{sourcesId}",
	//   "httpMethod": "GET",
	//   "id": "securitycenter.organizations.sources.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Relative resource name of the source. Its format is\n\"organizations/[organization_id]/source/[source_id]\".",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/sources/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "Source"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "securitycenter.organizations.sources.getIamPolicy":

type OrganizationsSourcesGetIamPolicyCall struct {
	s                   *Service
	resource            string
	getiampolicyrequest *GetIamPolicyRequest
	urlParams_          gensupport.URLParams
	ctx_                context.Context
	header_             http.Header
}

// GetIamPolicy: Gets the access control policy on the specified Source.
func (r *OrganizationsSourcesService) GetIamPolicy(resource string, getiampolicyrequest *GetIamPolicyRequest) *OrganizationsSourcesGetIamPolicyCall {
	c := &OrganizationsSourcesGetIamPolicyCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.resource = resource
	c.getiampolicyrequest = getiampolicyrequest
	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 *OrganizationsSourcesGetIamPolicyCall) Fields(s ...googleapi.Field) *OrganizationsSourcesGetIamPolicyCall {
	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 *OrganizationsSourcesGetIamPolicyCall) Context(ctx context.Context) *OrganizationsSourcesGetIamPolicyCall {
	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 *OrganizationsSourcesGetIamPolicyCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsSourcesGetIamPolicyCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200315")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.getiampolicyrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+resource}:getIamPolicy")
	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{
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "securitycenter.organizations.sources.getIamPolicy" call.
// Exactly one of *Policy or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Policy.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 *OrganizationsSourcesGetIamPolicyCall) Do(opts ...googleapi.CallOption) (*Policy, 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 := &Policy{
		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 access control policy on the specified Source.",
	//   "flatPath": "v1/organizations/{organizationsId}/sources/{sourcesId}:getIamPolicy",
	//   "httpMethod": "POST",
	//   "id": "securitycenter.organizations.sources.getIamPolicy",
	//   "parameterOrder": [
	//     "resource"
	//   ],
	//   "parameters": {
	//     "resource": {
	//       "description": "REQUIRED: The resource for which the policy is being requested.\nSee the operation documentation for the appropriate value for this field.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/sources/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+resource}:getIamPolicy",
	//   "request": {
	//     "$ref": "GetIamPolicyRequest"
	//   },
	//   "response": {
	//     "$ref": "Policy"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

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

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

// List: Lists all sources belonging to an organization.
func (r *OrganizationsSourcesService) List(parent string) *OrganizationsSourcesListCall {
	c := &OrganizationsSourcesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number
// of results to return in a single response. Default is
// 10, minimum is 1, maximum is 1000.
func (c *OrganizationsSourcesListCall) PageSize(pageSize int64) *OrganizationsSourcesListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The value returned
// by the last `ListSourcesResponse`; indicates
// that this is a continuation of a prior `ListSources` call, and
// that the system should return the next page of data.
func (c *OrganizationsSourcesListCall) PageToken(pageToken string) *OrganizationsSourcesListCall {
	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 *OrganizationsSourcesListCall) Fields(s ...googleapi.Field) *OrganizationsSourcesListCall {
	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 *OrganizationsSourcesListCall) IfNoneMatch(entityTag string) *OrganizationsSourcesListCall {
	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 *OrganizationsSourcesListCall) Context(ctx context.Context) *OrganizationsSourcesListCall {
	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 *OrganizationsSourcesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsSourcesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200315")
	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, "v1/{+parent}/sources")
	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{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "securitycenter.organizations.sources.list" call.
// Exactly one of *ListSourcesResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListSourcesResponse.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 *OrganizationsSourcesListCall) Do(opts ...googleapi.CallOption) (*ListSourcesResponse, 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 := &ListSourcesResponse{
		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 all sources belonging to an organization.",
	//   "flatPath": "v1/organizations/{organizationsId}/sources",
	//   "httpMethod": "GET",
	//   "id": "securitycenter.organizations.sources.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "pageSize": {
	//       "description": "The maximum number of results to return in a single response. Default is\n10, minimum is 1, maximum is 1000.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The value returned by the last `ListSourcesResponse`; indicates\nthat this is a continuation of a prior `ListSources` call, and\nthat the system should return the next page of data.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. Resource name of the parent of sources to list. Its format should be\n\"organizations/[organization_id]\".",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/sources",
	//   "response": {
	//     "$ref": "ListSourcesResponse"
	//   },
	//   "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 *OrganizationsSourcesListCall) Pages(ctx context.Context, f func(*ListSourcesResponse) 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)
	}
}

// method id "securitycenter.organizations.sources.patch":

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

// Patch: Updates a source.
func (r *OrganizationsSourcesService) Patch(name string, source *Source) *OrganizationsSourcesPatchCall {
	c := &OrganizationsSourcesPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.source = source
	return c
}

// UpdateMask sets the optional parameter "updateMask": The FieldMask to
// use when updating the source resource.
//
// If empty all mutable fields will be updated.
func (c *OrganizationsSourcesPatchCall) UpdateMask(updateMask string) *OrganizationsSourcesPatchCall {
	c.urlParams_.Set("updateMask", updateMask)
	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 *OrganizationsSourcesPatchCall) Fields(s ...googleapi.Field) *OrganizationsSourcesPatchCall {
	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 *OrganizationsSourcesPatchCall) Context(ctx context.Context) *OrganizationsSourcesPatchCall {
	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 *OrganizationsSourcesPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsSourcesPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200315")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.source)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PATCH", 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.sources.patch" call.
// Exactly one of *Source or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Source.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 *OrganizationsSourcesPatchCall) Do(opts ...googleapi.CallOption) (*Source, 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 := &Source{
		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": "Updates a source.",
	//   "flatPath": "v1/organizations/{organizationsId}/sources/{sourcesId}",
	//   "httpMethod": "PATCH",
	//   "id": "securitycenter.organizations.sources.patch",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The relative resource name of this source. See:\nhttps://cloud.google.com/apis/design/resource_names#relative_resource_name\nExample:\n\"organizations/{organization_id}/sources/{source_id}\"",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/sources/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "updateMask": {
	//       "description": "The FieldMask to use when updating the source resource.\n\nIf empty all mutable fields will be updated.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "request": {
	//     "$ref": "Source"
	//   },
	//   "response": {
	//     "$ref": "Source"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "securitycenter.organizations.sources.setIamPolicy":

type OrganizationsSourcesSetIamPolicyCall struct {
	s                   *Service
	resource            string
	setiampolicyrequest *SetIamPolicyRequest
	urlParams_          gensupport.URLParams
	ctx_                context.Context
	header_             http.Header
}

// SetIamPolicy: Sets the access control policy on the specified Source.
func (r *OrganizationsSourcesService) SetIamPolicy(resource string, setiampolicyrequest *SetIamPolicyRequest) *OrganizationsSourcesSetIamPolicyCall {
	c := &OrganizationsSourcesSetIamPolicyCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.resource = resource
	c.setiampolicyrequest = setiampolicyrequest
	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 *OrganizationsSourcesSetIamPolicyCall) Fields(s ...googleapi.Field) *OrganizationsSourcesSetIamPolicyCall {
	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 *OrganizationsSourcesSetIamPolicyCall) Context(ctx context.Context) *OrganizationsSourcesSetIamPolicyCall {
	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 *OrganizationsSourcesSetIamPolicyCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsSourcesSetIamPolicyCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200315")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.setiampolicyrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+resource}:setIamPolicy")
	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{
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "securitycenter.organizations.sources.setIamPolicy" call.
// Exactly one of *Policy or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Policy.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 *OrganizationsSourcesSetIamPolicyCall) Do(opts ...googleapi.CallOption) (*Policy, 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 := &Policy{
		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": "Sets the access control policy on the specified Source.",
	//   "flatPath": "v1/organizations/{organizationsId}/sources/{sourcesId}:setIamPolicy",
	//   "httpMethod": "POST",
	//   "id": "securitycenter.organizations.sources.setIamPolicy",
	//   "parameterOrder": [
	//     "resource"
	//   ],
	//   "parameters": {
	//     "resource": {
	//       "description": "REQUIRED: The resource for which the policy is being specified.\nSee the operation documentation for the appropriate value for this field.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/sources/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+resource}:setIamPolicy",
	//   "request": {
	//     "$ref": "SetIamPolicyRequest"
	//   },
	//   "response": {
	//     "$ref": "Policy"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "securitycenter.organizations.sources.testIamPermissions":

type OrganizationsSourcesTestIamPermissionsCall struct {
	s                         *Service
	resource                  string
	testiampermissionsrequest *TestIamPermissionsRequest
	urlParams_                gensupport.URLParams
	ctx_                      context.Context
	header_                   http.Header
}

// TestIamPermissions: Returns the permissions that a caller has on the
// specified source.
func (r *OrganizationsSourcesService) TestIamPermissions(resource string, testiampermissionsrequest *TestIamPermissionsRequest) *OrganizationsSourcesTestIamPermissionsCall {
	c := &OrganizationsSourcesTestIamPermissionsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.resource = resource
	c.testiampermissionsrequest = testiampermissionsrequest
	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 *OrganizationsSourcesTestIamPermissionsCall) Fields(s ...googleapi.Field) *OrganizationsSourcesTestIamPermissionsCall {
	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 *OrganizationsSourcesTestIamPermissionsCall) Context(ctx context.Context) *OrganizationsSourcesTestIamPermissionsCall {
	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 *OrganizationsSourcesTestIamPermissionsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsSourcesTestIamPermissionsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200315")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.testiampermissionsrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+resource}:testIamPermissions")
	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{
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "securitycenter.organizations.sources.testIamPermissions" call.
// Exactly one of *TestIamPermissionsResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *TestIamPermissionsResponse.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 *OrganizationsSourcesTestIamPermissionsCall) Do(opts ...googleapi.CallOption) (*TestIamPermissionsResponse, 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 := &TestIamPermissionsResponse{
		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": "Returns the permissions that a caller has on the specified source.",
	//   "flatPath": "v1/organizations/{organizationsId}/sources/{sourcesId}:testIamPermissions",
	//   "httpMethod": "POST",
	//   "id": "securitycenter.organizations.sources.testIamPermissions",
	//   "parameterOrder": [
	//     "resource"
	//   ],
	//   "parameters": {
	//     "resource": {
	//       "description": "REQUIRED: The resource for which the policy detail is being requested.\nSee the operation documentation for the appropriate value for this field.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/sources/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+resource}:testIamPermissions",
	//   "request": {
	//     "$ref": "TestIamPermissionsRequest"
	//   },
	//   "response": {
	//     "$ref": "TestIamPermissionsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "securitycenter.organizations.sources.findings.create":

type OrganizationsSourcesFindingsCreateCall struct {
	s          *Service
	parent     string
	finding    *Finding
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Create: Creates a finding. The corresponding source must exist for
// finding creation
// to succeed.
func (r *OrganizationsSourcesFindingsService) Create(parent string, finding *Finding) *OrganizationsSourcesFindingsCreateCall {
	c := &OrganizationsSourcesFindingsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.finding = finding
	return c
}

// FindingId sets the optional parameter "findingId": Required. Unique
// identifier provided by the client within the parent scope.
// It must be alphanumeric and less than or equal to 32 characters
// and
// greater than 0 characters in length.
func (c *OrganizationsSourcesFindingsCreateCall) FindingId(findingId string) *OrganizationsSourcesFindingsCreateCall {
	c.urlParams_.Set("findingId", findingId)
	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 *OrganizationsSourcesFindingsCreateCall) Fields(s ...googleapi.Field) *OrganizationsSourcesFindingsCreateCall {
	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 *OrganizationsSourcesFindingsCreateCall) Context(ctx context.Context) *OrganizationsSourcesFindingsCreateCall {
	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 *OrganizationsSourcesFindingsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsSourcesFindingsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200315")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.finding)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/findings")
	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{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "securitycenter.organizations.sources.findings.create" call.
// Exactly one of *Finding or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Finding.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 *OrganizationsSourcesFindingsCreateCall) Do(opts ...googleapi.CallOption) (*Finding, 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 := &Finding{
		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": "Creates a finding. The corresponding source must exist for finding creation\nto succeed.",
	//   "flatPath": "v1/organizations/{organizationsId}/sources/{sourcesId}/findings",
	//   "httpMethod": "POST",
	//   "id": "securitycenter.organizations.sources.findings.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "findingId": {
	//       "description": "Required. Unique identifier provided by the client within the parent scope.\nIt must be alphanumeric and less than or equal to 32 characters and\ngreater than 0 characters in length.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. Resource name of the new finding's parent. Its format should be\n\"organizations/[organization_id]/sources/[source_id]\".",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/sources/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/findings",
	//   "request": {
	//     "$ref": "Finding"
	//   },
	//   "response": {
	//     "$ref": "Finding"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "securitycenter.organizations.sources.findings.group":

type OrganizationsSourcesFindingsGroupCall struct {
	s                    *Service
	parent               string
	groupfindingsrequest *GroupFindingsRequest
	urlParams_           gensupport.URLParams
	ctx_                 context.Context
	header_              http.Header
}

// Group: Filters an organization or source's findings and  groups them
// by their
// specified properties.
//
// To group across all sources provide a `-` as the source id.
// Example: /v1/organizations/{organization_id}/sources/-/findings
func (r *OrganizationsSourcesFindingsService) Group(parent string, groupfindingsrequest *GroupFindingsRequest) *OrganizationsSourcesFindingsGroupCall {
	c := &OrganizationsSourcesFindingsGroupCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.groupfindingsrequest = groupfindingsrequest
	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 *OrganizationsSourcesFindingsGroupCall) Fields(s ...googleapi.Field) *OrganizationsSourcesFindingsGroupCall {
	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 *OrganizationsSourcesFindingsGroupCall) Context(ctx context.Context) *OrganizationsSourcesFindingsGroupCall {
	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 *OrganizationsSourcesFindingsGroupCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsSourcesFindingsGroupCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200315")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.groupfindingsrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/findings:group")
	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{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "securitycenter.organizations.sources.findings.group" call.
// Exactly one of *GroupFindingsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GroupFindingsResponse.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 *OrganizationsSourcesFindingsGroupCall) Do(opts ...googleapi.CallOption) (*GroupFindingsResponse, 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 := &GroupFindingsResponse{
		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": "Filters an organization or source's findings and  groups them by their\nspecified properties.\n\nTo group across all sources provide a `-` as the source id.\nExample: /v1/organizations/{organization_id}/sources/-/findings",
	//   "flatPath": "v1/organizations/{organizationsId}/sources/{sourcesId}/findings:group",
	//   "httpMethod": "POST",
	//   "id": "securitycenter.organizations.sources.findings.group",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. Name of the source to groupBy. Its format is\n\"organizations/[organization_id]/sources/[source_id]\". To groupBy across\nall sources provide a source_id of `-`. For example:\norganizations/{organization_id}/sources/-",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/sources/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/findings:group",
	//   "request": {
	//     "$ref": "GroupFindingsRequest"
	//   },
	//   "response": {
	//     "$ref": "GroupFindingsResponse"
	//   },
	//   "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 *OrganizationsSourcesFindingsGroupCall) Pages(ctx context.Context, f func(*GroupFindingsResponse) error) error {
	c.ctx_ = ctx
	defer func(pt string) { c.groupfindingsrequest.PageToken = pt }(c.groupfindingsrequest.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.groupfindingsrequest.PageToken = x.NextPageToken
	}
}

// method id "securitycenter.organizations.sources.findings.list":

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

// List: Lists an organization or source's findings.
//
// To list across all sources provide a `-` as the source id.
// Example: /v1/organizations/{organization_id}/sources/-/findings
func (r *OrganizationsSourcesFindingsService) List(parent string) *OrganizationsSourcesFindingsListCall {
	c := &OrganizationsSourcesFindingsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// CompareDuration sets the optional parameter "compareDuration": When
// compare_duration is set, the ListFindingsResult's
// "state_change"
// attribute is updated to indicate whether the finding had its state
// changed,
// the finding's state remained unchanged, or if the finding was added
// in any
// state during the compare_duration period of time that precedes
// the
// read_time. This is the time between (read_time - compare_duration)
// and
// read_time.
//
// The state_change value is derived based on the presence and state of
// the
// finding at the two points in time. Intermediate state changes between
// the
// two times don't affect the result. For example, the results aren't
// affected
// if the finding is made inactive and then active again.
//
// Possible "state_change" values when compare_duration is specified:
//
// * "CHANGED":   indicates that the finding was present and matched the
// given
//                  filter at the start of compare_duration, but changed
// its
//                  state at read_time.
// * "UNCHANGED": indicates that the finding was present and matched the
// given
//                  filter at the start of compare_duration and did not
// change
//                  state at read_time.
// * "ADDED":     indicates that the finding did not match the given
// filter or
//                  was not present at the start of compare_duration,
// but was
//                  present at read_time.
// * "REMOVED":   indicates that the finding was present and matched
// the
//                  filter at the start of compare_duration, but did not
// match
//                  the filter at read_time.
//
// If compare_duration is not specified, then the only possible
// state_change
// is "UNUSED", which will be the state_change set for all findings
// present at
// read_time.
func (c *OrganizationsSourcesFindingsListCall) CompareDuration(compareDuration string) *OrganizationsSourcesFindingsListCall {
	c.urlParams_.Set("compareDuration", compareDuration)
	return c
}

// FieldMask sets the optional parameter "fieldMask": A field mask to
// specify the Finding fields to be listed in the response.
// An empty field mask will list all fields.
func (c *OrganizationsSourcesFindingsListCall) FieldMask(fieldMask string) *OrganizationsSourcesFindingsListCall {
	c.urlParams_.Set("fieldMask", fieldMask)
	return c
}

// Filter sets the optional parameter "filter": Expression that defines
// the filter to apply across findings.
// The expression is a list of one or more restrictions combined via
// logical
// operators `AND` and `OR`.
// Parentheses are supported, and `OR` has higher precedence than
// `AND`.
//
// Restrictions have the form `<field> <operator> <value>` and may have
// a `-`
// character in front of them to indicate negation. Examples include:
//
//  * name
//  * source_properties.a_property
//  * security_marks.marks.marka
//
// The supported operators are:
//
// * `=` for all value types.
// * `>`, `<`, `>=`, `<=` for integer values.
// * `:`, meaning substring matching, for strings.
//
// The supported value types are:
//
// * string literals in quotes.
// * integer literals without quotes.
// * boolean literals `true` and `false` without quotes.
//
// The following field and operator combinations are supported:
//
// name: `=`
// parent: `=`, `:`
// resource_name: `=`, `:`
// state: `=`, `:`
// category: `=`, `:`
// external_uri: `=`, `:`
// event_time: `=`, `>`, `<`, `>=`, `<=`
//
//   Usage: This should be milliseconds since epoch or an RFC3339
// string.
//   Examples:
//     "event_time = \"2019-06-10T16:07:18-07:00\""
//     "event_time = 1560208038000"
//
// security_marks.marks: `=`, `:`
// source_properties: `=`, `:`, `>`, `<`, `>=`, `<=`
//
// For example, `source_properties.size = 100` is a valid filter string.
func (c *OrganizationsSourcesFindingsListCall) Filter(filter string) *OrganizationsSourcesFindingsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// OrderBy sets the optional parameter "orderBy": Expression that
// defines what fields and order to use for sorting. The
// string value should follow SQL syntax: comma separated list of
// fields. For
// example: "name,resource_properties.a_property". The default sorting
// order
// is ascending. To specify descending order for a field, a suffix "
// desc"
// should be appended to the field name. For example:
// "name
// desc,source_properties.a_property". Redundant space characters in
// the
// syntax are insignificant. "name desc,source_properties.a_property"
// and "
// name     desc  ,   source_properties.a_property  " are
// equivalent.
//
// The following fields are
// supported:
// name
// parent
// state
// category
// resource_name
// event_time
// source_
// properties
// security_marks.marks
func (c *OrganizationsSourcesFindingsListCall) OrderBy(orderBy string) *OrganizationsSourcesFindingsListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number
// of results to return in a single response. Default is
// 10, minimum is 1, maximum is 1000.
func (c *OrganizationsSourcesFindingsListCall) PageSize(pageSize int64) *OrganizationsSourcesFindingsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The value returned
// by the last `ListFindingsResponse`; indicates
// that this is a continuation of a prior `ListFindings` call, and
// that the system should return the next page of data.
func (c *OrganizationsSourcesFindingsListCall) PageToken(pageToken string) *OrganizationsSourcesFindingsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// ReadTime sets the optional parameter "readTime": Time used as a
// reference point when filtering findings. The filter is
// limited to findings existing at the supplied time and their values
// are
// those at that specific time. Absence of this field will default to
// the
// API's version of NOW.
func (c *OrganizationsSourcesFindingsListCall) ReadTime(readTime string) *OrganizationsSourcesFindingsListCall {
	c.urlParams_.Set("readTime", readTime)
	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 *OrganizationsSourcesFindingsListCall) Fields(s ...googleapi.Field) *OrganizationsSourcesFindingsListCall {
	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 *OrganizationsSourcesFindingsListCall) IfNoneMatch(entityTag string) *OrganizationsSourcesFindingsListCall {
	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 *OrganizationsSourcesFindingsListCall) Context(ctx context.Context) *OrganizationsSourcesFindingsListCall {
	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 *OrganizationsSourcesFindingsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsSourcesFindingsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200315")
	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, "v1/{+parent}/findings")
	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{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "securitycenter.organizations.sources.findings.list" call.
// Exactly one of *ListFindingsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListFindingsResponse.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 *OrganizationsSourcesFindingsListCall) Do(opts ...googleapi.CallOption) (*ListFindingsResponse, 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 := &ListFindingsResponse{
		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 an organization or source's findings.\n\nTo list across all sources provide a `-` as the source id.\nExample: /v1/organizations/{organization_id}/sources/-/findings",
	//   "flatPath": "v1/organizations/{organizationsId}/sources/{sourcesId}/findings",
	//   "httpMethod": "GET",
	//   "id": "securitycenter.organizations.sources.findings.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "compareDuration": {
	//       "description": "When compare_duration is set, the ListFindingsResult's \"state_change\"\nattribute is updated to indicate whether the finding had its state changed,\nthe finding's state remained unchanged, or if the finding was added in any\nstate during the compare_duration period of time that precedes the\nread_time. This is the time between (read_time - compare_duration) and\nread_time.\n\nThe state_change value is derived based on the presence and state of the\nfinding at the two points in time. Intermediate state changes between the\ntwo times don't affect the result. For example, the results aren't affected\nif the finding is made inactive and then active again.\n\nPossible \"state_change\" values when compare_duration is specified:\n\n* \"CHANGED\":   indicates that the finding was present and matched the given\n                 filter at the start of compare_duration, but changed its\n                 state at read_time.\n* \"UNCHANGED\": indicates that the finding was present and matched the given\n                 filter at the start of compare_duration and did not change\n                 state at read_time.\n* \"ADDED\":     indicates that the finding did not match the given filter or\n                 was not present at the start of compare_duration, but was\n                 present at read_time.\n* \"REMOVED\":   indicates that the finding was present and matched the\n                 filter at the start of compare_duration, but did not match\n                 the filter at read_time.\n\nIf compare_duration is not specified, then the only possible state_change\nis \"UNUSED\", which will be the state_change set for all findings present at\nread_time.",
	//       "format": "google-duration",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "fieldMask": {
	//       "description": "Optional. A field mask to specify the Finding fields to be listed in the response.\nAn empty field mask will list all fields.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "filter": {
	//       "description": "Expression that defines the filter to apply across findings.\nThe expression is a list of one or more restrictions combined via logical\noperators `AND` and `OR`.\nParentheses are supported, and `OR` has higher precedence than `AND`.\n\nRestrictions have the form `\u003cfield\u003e \u003coperator\u003e \u003cvalue\u003e` and may have a `-`\ncharacter in front of them to indicate negation. Examples include:\n\n * name\n * source_properties.a_property\n * security_marks.marks.marka\n\nThe supported operators are:\n\n* `=` for all value types.\n* `\u003e`, `\u003c`, `\u003e=`, `\u003c=` for integer values.\n* `:`, meaning substring matching, for strings.\n\nThe supported value types are:\n\n* string literals in quotes.\n* integer literals without quotes.\n* boolean literals `true` and `false` without quotes.\n\nThe following field and operator combinations are supported:\n\nname: `=`\nparent: `=`, `:`\nresource_name: `=`, `:`\nstate: `=`, `:`\ncategory: `=`, `:`\nexternal_uri: `=`, `:`\nevent_time: `=`, `\u003e`, `\u003c`, `\u003e=`, `\u003c=`\n\n  Usage: This should be milliseconds since epoch or an RFC3339 string.\n  Examples:\n    \"event_time = \\\"2019-06-10T16:07:18-07:00\\\"\"\n    \"event_time = 1560208038000\"\n\nsecurity_marks.marks: `=`, `:`\nsource_properties: `=`, `:`, `\u003e`, `\u003c`, `\u003e=`, `\u003c=`\n\nFor example, `source_properties.size = 100` is a valid filter string.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "orderBy": {
	//       "description": "Expression that defines what fields and order to use for sorting. The\nstring value should follow SQL syntax: comma separated list of fields. For\nexample: \"name,resource_properties.a_property\". The default sorting order\nis ascending. To specify descending order for a field, a suffix \" desc\"\nshould be appended to the field name. For example: \"name\ndesc,source_properties.a_property\". Redundant space characters in the\nsyntax are insignificant. \"name desc,source_properties.a_property\" and \"\nname     desc  ,   source_properties.a_property  \" are equivalent.\n\nThe following fields are supported:\nname\nparent\nstate\ncategory\nresource_name\nevent_time\nsource_properties\nsecurity_marks.marks",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "The maximum number of results to return in a single response. Default is\n10, minimum is 1, maximum is 1000.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The value returned by the last `ListFindingsResponse`; indicates\nthat this is a continuation of a prior `ListFindings` call, and\nthat the system should return the next page of data.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. Name of the source the findings belong to. Its format is\n\"organizations/[organization_id]/sources/[source_id]\". To list across all\nsources provide a source_id of `-`. For example:\norganizations/{organization_id}/sources/-",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/sources/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "readTime": {
	//       "description": "Time used as a reference point when filtering findings. The filter is\nlimited to findings existing at the supplied time and their values are\nthose at that specific time. Absence of this field will default to the\nAPI's version of NOW.",
	//       "format": "google-datetime",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/findings",
	//   "response": {
	//     "$ref": "ListFindingsResponse"
	//   },
	//   "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 *OrganizationsSourcesFindingsListCall) Pages(ctx context.Context, f func(*ListFindingsResponse) 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)
	}
}

// method id "securitycenter.organizations.sources.findings.patch":

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

// Patch: Creates or updates a finding. The corresponding source must
// exist for a
// finding creation to succeed.
func (r *OrganizationsSourcesFindingsService) Patch(name string, finding *Finding) *OrganizationsSourcesFindingsPatchCall {
	c := &OrganizationsSourcesFindingsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.finding = finding
	return c
}

// UpdateMask sets the optional parameter "updateMask": The FieldMask to
// use when updating the finding resource. This field should
// not be specified when creating a finding.
//
// When updating a finding, an empty mask is treated as updating all
// mutable
// fields and replacing source_properties.  Individual source_properties
// can
// be added/updated by using "source_properties.<property key>" in the
// field
// mask.
func (c *OrganizationsSourcesFindingsPatchCall) UpdateMask(updateMask string) *OrganizationsSourcesFindingsPatchCall {
	c.urlParams_.Set("updateMask", updateMask)
	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 *OrganizationsSourcesFindingsPatchCall) Fields(s ...googleapi.Field) *OrganizationsSourcesFindingsPatchCall {
	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 *OrganizationsSourcesFindingsPatchCall) Context(ctx context.Context) *OrganizationsSourcesFindingsPatchCall {
	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 *OrganizationsSourcesFindingsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsSourcesFindingsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200315")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.finding)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PATCH", 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.sources.findings.patch" call.
// Exactly one of *Finding or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Finding.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 *OrganizationsSourcesFindingsPatchCall) Do(opts ...googleapi.CallOption) (*Finding, 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 := &Finding{
		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": "Creates or updates a finding. The corresponding source must exist for a\nfinding creation to succeed.",
	//   "flatPath": "v1/organizations/{organizationsId}/sources/{sourcesId}/findings/{findingsId}",
	//   "httpMethod": "PATCH",
	//   "id": "securitycenter.organizations.sources.findings.patch",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The relative resource name of this finding. See:\nhttps://cloud.google.com/apis/design/resource_names#relative_resource_name\nExample:\n\"organizations/{organization_id}/sources/{source_id}/findings/{finding_id}\"",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/sources/[^/]+/findings/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "updateMask": {
	//       "description": "The FieldMask to use when updating the finding resource. This field should\nnot be specified when creating a finding.\n\nWhen updating a finding, an empty mask is treated as updating all mutable\nfields and replacing source_properties.  Individual source_properties can\nbe added/updated by using \"source_properties.\u003cproperty key\u003e\" in the field\nmask.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "request": {
	//     "$ref": "Finding"
	//   },
	//   "response": {
	//     "$ref": "Finding"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "securitycenter.organizations.sources.findings.setState":

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

// SetState: Updates the state of a finding.
func (r *OrganizationsSourcesFindingsService) SetState(name string, setfindingstaterequest *SetFindingStateRequest) *OrganizationsSourcesFindingsSetStateCall {
	c := &OrganizationsSourcesFindingsSetStateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.setfindingstaterequest = setfindingstaterequest
	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 *OrganizationsSourcesFindingsSetStateCall) Fields(s ...googleapi.Field) *OrganizationsSourcesFindingsSetStateCall {
	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 *OrganizationsSourcesFindingsSetStateCall) Context(ctx context.Context) *OrganizationsSourcesFindingsSetStateCall {
	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 *OrganizationsSourcesFindingsSetStateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsSourcesFindingsSetStateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200315")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.setfindingstaterequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}:setState")
	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.sources.findings.setState" call.
// Exactly one of *Finding or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Finding.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 *OrganizationsSourcesFindingsSetStateCall) Do(opts ...googleapi.CallOption) (*Finding, 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 := &Finding{
		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": "Updates the state of a finding.",
	//   "flatPath": "v1/organizations/{organizationsId}/sources/{sourcesId}/findings/{findingsId}:setState",
	//   "httpMethod": "POST",
	//   "id": "securitycenter.organizations.sources.findings.setState",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The relative resource name of the finding. See:\nhttps://cloud.google.com/apis/design/resource_names#relative_resource_name\nExample:\n\"organizations/{organization_id}/sources/{source_id}/finding/{finding_id}\".",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/sources/[^/]+/findings/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}:setState",
	//   "request": {
	//     "$ref": "SetFindingStateRequest"
	//   },
	//   "response": {
	//     "$ref": "Finding"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "securitycenter.organizations.sources.findings.updateSecurityMarks":

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

// UpdateSecurityMarks: Updates security marks.
func (r *OrganizationsSourcesFindingsService) UpdateSecurityMarks(name string, securitymarks *SecurityMarks) *OrganizationsSourcesFindingsUpdateSecurityMarksCall {
	c := &OrganizationsSourcesFindingsUpdateSecurityMarksCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.securitymarks = securitymarks
	return c
}

// StartTime sets the optional parameter "startTime": The time at which
// the updated SecurityMarks take effect.
// If not set uses current server time.  Updates will be applied to
// the
// SecurityMarks that are active immediately preceding this time.
func (c *OrganizationsSourcesFindingsUpdateSecurityMarksCall) StartTime(startTime string) *OrganizationsSourcesFindingsUpdateSecurityMarksCall {
	c.urlParams_.Set("startTime", startTime)
	return c
}

// UpdateMask sets the optional parameter "updateMask": The FieldMask to
// use when updating the security marks resource.
//
// The field mask must not contain duplicate fields.
// If empty or set to "marks", all marks will be replaced.
// Individual
// marks can be updated using "marks.<mark_key>".
func (c *OrganizationsSourcesFindingsUpdateSecurityMarksCall) UpdateMask(updateMask string) *OrganizationsSourcesFindingsUpdateSecurityMarksCall {
	c.urlParams_.Set("updateMask", updateMask)
	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 *OrganizationsSourcesFindingsUpdateSecurityMarksCall) Fields(s ...googleapi.Field) *OrganizationsSourcesFindingsUpdateSecurityMarksCall {
	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 *OrganizationsSourcesFindingsUpdateSecurityMarksCall) Context(ctx context.Context) *OrganizationsSourcesFindingsUpdateSecurityMarksCall {
	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 *OrganizationsSourcesFindingsUpdateSecurityMarksCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsSourcesFindingsUpdateSecurityMarksCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200315")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.securitymarks)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PATCH", 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.sources.findings.updateSecurityMarks" call.
// Exactly one of *SecurityMarks or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *SecurityMarks.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 *OrganizationsSourcesFindingsUpdateSecurityMarksCall) Do(opts ...googleapi.CallOption) (*SecurityMarks, 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 := &SecurityMarks{
		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": "Updates security marks.",
	//   "flatPath": "v1/organizations/{organizationsId}/sources/{sourcesId}/findings/{findingsId}/securityMarks",
	//   "httpMethod": "PATCH",
	//   "id": "securitycenter.organizations.sources.findings.updateSecurityMarks",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The relative resource name of the SecurityMarks. See:\nhttps://cloud.google.com/apis/design/resource_names#relative_resource_name\nExamples:\n\"organizations/{organization_id}/assets/{asset_id}/securityMarks\"\n\"organizations/{organization_id}/sources/{source_id}/findings/{finding_id}/securityMarks\".",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/sources/[^/]+/findings/[^/]+/securityMarks$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "startTime": {
	//       "description": "The time at which the updated SecurityMarks take effect.\nIf not set uses current server time.  Updates will be applied to the\nSecurityMarks that are active immediately preceding this time.",
	//       "format": "google-datetime",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "updateMask": {
	//       "description": "The FieldMask to use when updating the security marks resource.\n\nThe field mask must not contain duplicate fields.\nIf empty or set to \"marks\", all marks will be replaced.  Individual\nmarks can be updated using \"marks.\u003cmark_key\u003e\".",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "request": {
	//     "$ref": "SecurityMarks"
	//   },
	//   "response": {
	//     "$ref": "SecurityMarks"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}
