// 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 osconfig provides access to the OS Config API.
//
// For product documentation, see: https://cloud.google.com/compute/docs/manage-os
//
// Creating a client
//
// Usage example:
//
//   import "google.golang.org/api/osconfig/v1beta"
//   ...
//   ctx := context.Background()
//   osconfigService, err := osconfig.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:
//
//   osconfigService, err := osconfig.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, ...)
//   osconfigService, err := osconfig.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See https://godoc.org/google.golang.org/api/option/ for details on options.
package osconfig // import "google.golang.org/api/osconfig/v1beta"

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 = "osconfig:v1beta"
const apiName = "osconfig"
const apiVersion = "v1beta"
const basePath = "https://osconfig.googleapis.com/"
const mtlsBasePath = "https://osconfig.mtls.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))
	opts = append(opts, internaloption.WithDefaultMTLSEndpoint(mtlsBasePath))
	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.Projects = NewProjectsService(s)
	return s, nil
}

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

	Projects *ProjectsService
}

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

func NewProjectsService(s *Service) *ProjectsService {
	rs := &ProjectsService{s: s}
	rs.GuestPolicies = NewProjectsGuestPoliciesService(s)
	rs.PatchDeployments = NewProjectsPatchDeploymentsService(s)
	rs.PatchJobs = NewProjectsPatchJobsService(s)
	rs.Zones = NewProjectsZonesService(s)
	return rs
}

type ProjectsService struct {
	s *Service

	GuestPolicies *ProjectsGuestPoliciesService

	PatchDeployments *ProjectsPatchDeploymentsService

	PatchJobs *ProjectsPatchJobsService

	Zones *ProjectsZonesService
}

func NewProjectsGuestPoliciesService(s *Service) *ProjectsGuestPoliciesService {
	rs := &ProjectsGuestPoliciesService{s: s}
	return rs
}

type ProjectsGuestPoliciesService struct {
	s *Service
}

func NewProjectsPatchDeploymentsService(s *Service) *ProjectsPatchDeploymentsService {
	rs := &ProjectsPatchDeploymentsService{s: s}
	return rs
}

type ProjectsPatchDeploymentsService struct {
	s *Service
}

func NewProjectsPatchJobsService(s *Service) *ProjectsPatchJobsService {
	rs := &ProjectsPatchJobsService{s: s}
	rs.InstanceDetails = NewProjectsPatchJobsInstanceDetailsService(s)
	return rs
}

type ProjectsPatchJobsService struct {
	s *Service

	InstanceDetails *ProjectsPatchJobsInstanceDetailsService
}

func NewProjectsPatchJobsInstanceDetailsService(s *Service) *ProjectsPatchJobsInstanceDetailsService {
	rs := &ProjectsPatchJobsInstanceDetailsService{s: s}
	return rs
}

type ProjectsPatchJobsInstanceDetailsService struct {
	s *Service
}

func NewProjectsZonesService(s *Service) *ProjectsZonesService {
	rs := &ProjectsZonesService{s: s}
	rs.Instances = NewProjectsZonesInstancesService(s)
	return rs
}

type ProjectsZonesService struct {
	s *Service

	Instances *ProjectsZonesInstancesService
}

func NewProjectsZonesInstancesService(s *Service) *ProjectsZonesInstancesService {
	rs := &ProjectsZonesInstancesService{s: s}
	return rs
}

type ProjectsZonesInstancesService struct {
	s *Service
}

// AptRepository: Represents a single Apt package repository. This
// repository is added to a repo file that is stored at
// `/etc/apt/sources.list.d/google_osconfig.list`.
type AptRepository struct {
	// ArchiveType: Type of archive files in this repository. The default
	// behavior is DEB.
	//
	// Possible values:
	//   "ARCHIVE_TYPE_UNSPECIFIED" - Unspecified.
	//   "DEB" - DEB indicates that the archive contains binary files.
	//   "DEB_SRC" - DEB_SRC indicates that the archive contains source
	// files.
	ArchiveType string `json:"archiveType,omitempty"`

	// Components: Required. List of components for this repository. Must
	// contain at least one item.
	Components []string `json:"components,omitempty"`

	// Distribution: Required. Distribution of this repository.
	Distribution string `json:"distribution,omitempty"`

	// GpgKey: URI of the key file for this repository. The agent maintains
	// a keyring at `/etc/apt/trusted.gpg.d/osconfig_agent_managed.gpg`
	// containing all the keys in any applied guest policy.
	GpgKey string `json:"gpgKey,omitempty"`

	// Uri: Required. URI for this repository.
	Uri string `json:"uri,omitempty"`

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

// AptSettings: Apt patching is completed by executing `apt-get update
// && apt-get upgrade`. Additional options can be set to control how
// this is executed.
type AptSettings struct {
	// Excludes: List of packages to exclude from update. These packages
	// will be excluded
	Excludes []string `json:"excludes,omitempty"`

	// ExclusivePackages: An exclusive list of packages to be updated. These
	// are the only packages that will be updated. If these packages are not
	// installed, they will be ignored. This field cannot be specified with
	// any other patch configuration fields.
	ExclusivePackages []string `json:"exclusivePackages,omitempty"`

	// Type: By changing the type to DIST, the patching is performed using
	// `apt-get dist-upgrade` instead.
	//
	// Possible values:
	//   "TYPE_UNSPECIFIED" - By default, upgrade will be performed.
	//   "DIST" - Runs `apt-get dist-upgrade`.
	//   "UPGRADE" - Runs `apt-get upgrade`.
	Type string `json:"type,omitempty"`

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

// Assignment: An assignment represents the group or groups of VM
// instances that the policy applies to. If an assignment is empty, it
// applies to all VM instances. Otherwise, the targeted VM instances
// must meet all the criteria specified. So if both labels and zones are
// specified, the policy applies to VM instances with those labels and
// in those zones.
type Assignment struct {
	// GroupLabels: Targets instances matching at least one of these label
	// sets. This allows an assignment to target disparate groups, for
	// example "env=prod or env=staging".
	GroupLabels []*AssignmentGroupLabel `json:"groupLabels,omitempty"`

	// InstanceNamePrefixes: Targets VM instances whose name starts with one
	// of these prefixes. Like labels, this is another way to group VM
	// instances when targeting configs, for example prefix="prod-". Only
	// supported for project-level policies.
	InstanceNamePrefixes []string `json:"instanceNamePrefixes,omitempty"`

	// Instances: Targets any of the instances specified. Instances are
	// specified by their URI in the form
	// `zones/[ZONE]/instances/[INSTANCE_NAME]`. Instance targeting is
	// uncommon and is supported to facilitate the management of changes by
	// the instance or to target specific VM instances for development and
	// testing. Only supported for project-level policies and must reference
	// instances within this project.
	Instances []string `json:"instances,omitempty"`

	// OsTypes: Targets VM instances matching at least one of the following
	// OS types. VM instances must match all supplied criteria for a given
	// OsType to be included.
	OsTypes []*AssignmentOsType `json:"osTypes,omitempty"`

	// Zones: Targets instances in any of these zones. Leave empty to target
	// instances in any zone. Zonal targeting is uncommon and is supported
	// to facilitate the management of changes by zone.
	Zones []string `json:"zones,omitempty"`

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

// AssignmentGroupLabel: Represents a group of VM intances that can be
// identified as having all these labels, for example "env=prod and
// app=web".
type AssignmentGroupLabel struct {
	// Labels: Google Compute Engine instance labels that must be present
	// for an instance to be included in this assignment group.
	Labels map[string]string `json:"labels,omitempty"`

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

// AssignmentOsType: Defines the criteria for selecting VM Instances by
// OS type.
type AssignmentOsType struct {
	// OsArchitecture: Targets VM instances with OS Inventory enabled and
	// having the following OS architecture.
	OsArchitecture string `json:"osArchitecture,omitempty"`

	// OsShortName: Targets VM instances with OS Inventory enabled and
	// having the following OS short name, for example "debian" or
	// "windows".
	OsShortName string `json:"osShortName,omitempty"`

	// OsVersion: Targets VM instances with OS Inventory enabled and having
	// the following following OS version.
	OsVersion string `json:"osVersion,omitempty"`

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

// CancelPatchJobRequest: Message for canceling a patch job.
type CancelPatchJobRequest struct {
}

// EffectiveGuestPolicy: The effective guest policy that applies to a VM
// instance.
type EffectiveGuestPolicy struct {
	// PackageRepositories: List of package repository configurations
	// assigned to the VM instance.
	PackageRepositories []*EffectiveGuestPolicySourcedPackageRepository `json:"packageRepositories,omitempty"`

	// Packages: List of package configurations assigned to the VM instance.
	Packages []*EffectiveGuestPolicySourcedPackage `json:"packages,omitempty"`

	// SoftwareRecipes: List of recipes assigned to the VM instance.
	SoftwareRecipes []*EffectiveGuestPolicySourcedSoftwareRecipe `json:"softwareRecipes,omitempty"`

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

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

// EffectiveGuestPolicySourcedPackage: A guest policy package including
// its source.
type EffectiveGuestPolicySourcedPackage struct {
	// Package: A software package to configure on the VM instance.
	Package *Package `json:"package,omitempty"`

	// Source: Name of the guest policy providing this config.
	Source string `json:"source,omitempty"`

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

// EffectiveGuestPolicySourcedPackageRepository: A guest policy package
// repository including its source.
type EffectiveGuestPolicySourcedPackageRepository struct {
	// PackageRepository: A software package repository to configure on the
	// VM instance.
	PackageRepository *PackageRepository `json:"packageRepository,omitempty"`

	// Source: Name of the guest policy providing this config.
	Source string `json:"source,omitempty"`

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

// EffectiveGuestPolicySourcedSoftwareRecipe: A guest policy recipe
// including its source.
type EffectiveGuestPolicySourcedSoftwareRecipe struct {
	// SoftwareRecipe: A software recipe to configure on the VM instance.
	SoftwareRecipe *SoftwareRecipe `json:"softwareRecipe,omitempty"`

	// Source: Name of the guest policy providing this config.
	Source string `json:"source,omitempty"`

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

// ExecStep: A step that runs an executable for a PatchJob.
type ExecStep struct {
	// LinuxExecStepConfig: The ExecStepConfig for all Linux VMs targeted by
	// the PatchJob.
	LinuxExecStepConfig *ExecStepConfig `json:"linuxExecStepConfig,omitempty"`

	// WindowsExecStepConfig: The ExecStepConfig for all Windows VMs
	// targeted by the PatchJob.
	WindowsExecStepConfig *ExecStepConfig `json:"windowsExecStepConfig,omitempty"`

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

// ExecStepConfig: Common configurations for an ExecStep.
type ExecStepConfig struct {
	// AllowedSuccessCodes: Defaults to [0]. A list of possible return
	// values that the execution can return to indicate a success.
	AllowedSuccessCodes []int64 `json:"allowedSuccessCodes,omitempty"`

	// GcsObject: A Google Cloud Storage object containing the executable.
	GcsObject *GcsObject `json:"gcsObject,omitempty"`

	// Interpreter: The script interpreter to use to run the script. If no
	// interpreter is specified the script will be executed directly, which
	// will likely only succeed for scripts with [shebang lines]
	// (https://en.wikipedia.org/wiki/Shebang_\(Unix\)).
	//
	// Possible values:
	//   "INTERPRETER_UNSPECIFIED" - Invalid for a Windows ExecStepConfig.
	// For a Linux ExecStepConfig, the interpreter will be parsed from the
	// shebang line of the script if unspecified.
	//   "SHELL" - Indicates that the script is run with `/bin/sh` on Linux
	// and `cmd` on Windows.
	//   "POWERSHELL" - Indicates that the file is run with PowerShell flags
	// `-NonInteractive`, `-NoProfile`, and `-ExecutionPolicy Bypass`.
	Interpreter string `json:"interpreter,omitempty"`

	// LocalPath: An absolute path to the executable on the VM.
	LocalPath string `json:"localPath,omitempty"`

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

// ExecutePatchJobRequest: A request message to initiate patching across
// Compute Engine instances.
type ExecutePatchJobRequest struct {
	// Description: Description of the patch job. Length of the description
	// is limited to 1024 characters.
	Description string `json:"description,omitempty"`

	// DisplayName: Display name for this patch job. This does not have to
	// be unique.
	DisplayName string `json:"displayName,omitempty"`

	// DryRun: If this patch is a dry-run only, instances are contacted but
	// will do nothing.
	DryRun bool `json:"dryRun,omitempty"`

	// Duration: Duration of the patch job. After the duration ends, the
	// patch job times out.
	Duration string `json:"duration,omitempty"`

	// InstanceFilter: Required. Instances to patch, either explicitly or
	// filtered by some criteria such as zone or labels.
	InstanceFilter *PatchInstanceFilter `json:"instanceFilter,omitempty"`

	// PatchConfig: Patch configuration being applied. If omitted, instances
	// are patched using the default configurations.
	PatchConfig *PatchConfig `json:"patchConfig,omitempty"`

	// Rollout: Rollout strategy of the patch job.
	Rollout *PatchRollout `json:"rollout,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 *ExecutePatchJobRequest) MarshalJSON() ([]byte, error) {
	type NoMethod ExecutePatchJobRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// FixedOrPercent: Message encapsulating a value that can be either
// absolute ("fixed") or relative ("percent") to a value.
type FixedOrPercent struct {
	// Fixed: Specifies a fixed value.
	Fixed int64 `json:"fixed,omitempty"`

	// Percent: Specifies the relative value defined as a percentage, which
	// will be multiplied by a reference value.
	Percent int64 `json:"percent,omitempty"`

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

// GcsObject: Google Cloud Storage object representation.
type GcsObject struct {
	// Bucket: Required. Bucket of the Google Cloud Storage object.
	Bucket string `json:"bucket,omitempty"`

	// GenerationNumber: Required. Generation number of the Google Cloud
	// Storage object. This is used to ensure that the ExecStep specified by
	// this PatchJob does not change.
	GenerationNumber int64 `json:"generationNumber,omitempty,string"`

	// Object: Required. Name of the Google Cloud Storage object.
	Object string `json:"object,omitempty"`

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

// GooRepository: Represents a Goo package repository. These is added to
// a repo file that is stored at
// C:/ProgramData/GooGet/repos/google_osconfig.repo.
type GooRepository struct {
	// Name: Required. The name of the repository.
	Name string `json:"name,omitempty"`

	// Url: Required. The url of the repository.
	Url string `json:"url,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 *GooRepository) MarshalJSON() ([]byte, error) {
	type NoMethod GooRepository
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GooSettings: Googet patching is performed by running `googet update`.
type GooSettings struct {
}

// GuestPolicy: An OS Config resource representing a guest configuration
// policy. These policies represent the desired state for VM instance
// guest environments including packages to install or remove, package
// repository configurations, and software to install.
type GuestPolicy struct {
	// Assignment: Required. Specifies the VM instances that are assigned to
	// this policy. This allows you to target sets or groups of VM instances
	// by different parameters such as labels, names, OS, or zones. If left
	// empty, all VM instances underneath this policy are targeted. At the
	// same level in the resource hierarchy (that is within a project), the
	// service prevents the creation of multiple policies that conflict with
	// each other. For more information, see how the service [handles
	// assignment
	// conflicts](/compute/docs/os-config-management/create-guest-policy#hand
	// le-conflicts).
	Assignment *Assignment `json:"assignment,omitempty"`

	// CreateTime: Output only. Time this guest policy was created.
	CreateTime string `json:"createTime,omitempty"`

	// Description: Description of the guest policy. Length of the
	// description is limited to 1024 characters.
	Description string `json:"description,omitempty"`

	// Etag: The etag for this guest policy. If this is provided on update,
	// it must match the server's etag.
	Etag string `json:"etag,omitempty"`

	// Name: Required. Unique name of the resource in this project using one
	// of the following forms:
	// `projects/{project_number}/guestPolicies/{guest_policy_id}`.
	Name string `json:"name,omitempty"`

	// PackageRepositories: A list of package repositories to configure on
	// the VM instance. This is done before any other configs are applied so
	// they can use these repos. Package repositories are only configured if
	// the corresponding package manager(s) are available.
	PackageRepositories []*PackageRepository `json:"packageRepositories,omitempty"`

	// Packages: The software packages to be managed by this policy.
	Packages []*Package `json:"packages,omitempty"`

	// Recipes: A list of Recipes to install on the VM instance.
	Recipes []*SoftwareRecipe `json:"recipes,omitempty"`

	// UpdateTime: Output only. Last time this guest policy was updated.
	UpdateTime string `json:"updateTime,omitempty"`

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

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

// ListGuestPoliciesResponse: A response message for listing guest
// policies.
type ListGuestPoliciesResponse struct {
	// GuestPolicies: The list of GuestPolicies.
	GuestPolicies []*GuestPolicy `json:"guestPolicies,omitempty"`

	// NextPageToken: A pagination token that can be used to get the next
	// page of guest policies.
	NextPageToken string `json:"nextPageToken,omitempty"`

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

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

// ListPatchDeploymentsResponse: A response message for listing patch
// deployments.
type ListPatchDeploymentsResponse struct {
	// NextPageToken: A pagination token that can be used to get the next
	// page of patch deployments.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// PatchDeployments: The list of patch deployments.
	PatchDeployments []*PatchDeployment `json:"patchDeployments,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 *ListPatchDeploymentsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListPatchDeploymentsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ListPatchJobInstanceDetailsResponse: A response message for listing
// the instances details for a patch job.
type ListPatchJobInstanceDetailsResponse struct {
	// NextPageToken: A pagination token that can be used to get the next
	// page of results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// PatchJobInstanceDetails: A list of instance status.
	PatchJobInstanceDetails []*PatchJobInstanceDetails `json:"patchJobInstanceDetails,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 *ListPatchJobInstanceDetailsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListPatchJobInstanceDetailsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ListPatchJobsResponse: A response message for listing patch jobs.
type ListPatchJobsResponse struct {
	// NextPageToken: A pagination token that can be used to get the next
	// page of results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// PatchJobs: The list of patch jobs.
	PatchJobs []*PatchJob `json:"patchJobs,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 *ListPatchJobsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListPatchJobsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// LookupEffectiveGuestPolicyRequest: A request message for getting the
// effective guest policy assigned to the instance.
type LookupEffectiveGuestPolicyRequest struct {
	// OsArchitecture: Architecture of OS running on the instance. The OS
	// Config agent only provides this field for targeting if OS Inventory
	// is enabled for that instance.
	OsArchitecture string `json:"osArchitecture,omitempty"`

	// OsShortName: Short name of the OS running on the instance. The OS
	// Config agent only provides this field for targeting if OS Inventory
	// is enabled for that instance.
	OsShortName string `json:"osShortName,omitempty"`

	// OsVersion: Version of the OS running on the instance. The OS Config
	// agent only provides this field for targeting if OS Inventory is
	// enabled for that VM instance.
	OsVersion string `json:"osVersion,omitempty"`

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

// MonthlySchedule: Represents a monthly schedule. An example of a valid
// monthly schedule is "on the third Tuesday of the month" or "on the
// 15th of the month".
type MonthlySchedule struct {
	// MonthDay: Required. One day of the month. 1-31 indicates the 1st to
	// the 31st day. -1 indicates the last day of the month. Months without
	// the target day will be skipped. For example, a schedule to run "every
	// month on the 31st" will not run in February, April, June, etc.
	MonthDay int64 `json:"monthDay,omitempty"`

	// WeekDayOfMonth: Required. Week day in a month.
	WeekDayOfMonth *WeekDayOfMonth `json:"weekDayOfMonth,omitempty"`

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

// OneTimeSchedule: Sets the time for a one time patch deployment.
// Timestamp is in [RFC3339](https://www.ietf.org/rfc/rfc3339.txt) text
// format.
type OneTimeSchedule struct {
	// ExecuteTime: Required. The desired patch job execution time.
	ExecuteTime string `json:"executeTime,omitempty"`

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

// Package: Package is a reference to the software package to be
// installed or removed. The agent on the VM instance uses the system
// package manager to apply the config. These are the commands that the
// agent uses to install or remove packages. Apt install: `apt-get
// update && apt-get -y install package1 package2 package3` remove:
// `apt-get -y remove package1 package2 package3` Yum install: `yum -y
// install package1 package2 package3` remove: `yum -y remove package1
// package2 package3` Zypper install: `zypper install package1 package2
// package3` remove: `zypper rm package1 package2` Googet install:
// `googet -noconfirm install package1 package2 package3` remove:
// `googet -noconfirm remove package1 package2 package3`
type Package struct {
	// DesiredState: The desired_state the agent should maintain for this
	// package. The default is to ensure the package is installed.
	//
	// Possible values:
	//   "DESIRED_STATE_UNSPECIFIED" - The default is to ensure the package
	// is installed.
	//   "INSTALLED" - The agent ensures that the package is installed.
	//   "UPDATED" - The agent ensures that the package is installed and
	// periodically checks for and install any updates.
	//   "REMOVED" - The agent ensures that the package is not installed and
	// uninstall it if detected.
	DesiredState string `json:"desiredState,omitempty"`

	// Manager: Type of package manager that can be used to install this
	// package. If a system does not have the package manager, the package
	// is not installed or removed no error message is returned. By default,
	// or if you specify `ANY`, the agent attempts to install and remove
	// this package using the default package manager. This is useful when
	// creating a policy that applies to different types of systems. The
	// default behavior is ANY.
	//
	// Possible values:
	//   "MANAGER_UNSPECIFIED" - The default behavior is ANY.
	//   "ANY" - Apply this package config using the default system package
	// manager.
	//   "APT" - Apply this package config only if Apt is available on the
	// system.
	//   "YUM" - Apply this package config only if Yum is available on the
	// system.
	//   "ZYPPER" - Apply this package config only if Zypper is available on
	// the system.
	//   "GOO" - Apply this package config only if GooGet is available on
	// the system.
	Manager string `json:"manager,omitempty"`

	// Name: Required. The name of the package. A package is uniquely
	// identified for conflict validation by checking the package name and
	// the manager(s) that the package targets.
	Name string `json:"name,omitempty"`

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

// PackageRepository: A package repository.
type PackageRepository struct {
	// Apt: An Apt Repository.
	Apt *AptRepository `json:"apt,omitempty"`

	// Goo: A Goo Repository.
	Goo *GooRepository `json:"goo,omitempty"`

	// Yum: A Yum Repository.
	Yum *YumRepository `json:"yum,omitempty"`

	// Zypper: A Zypper Repository.
	Zypper *ZypperRepository `json:"zypper,omitempty"`

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

// PatchConfig: Patch configuration specifications. Contains details on
// how to apply the patch(es) to a VM instance.
type PatchConfig struct {
	// Apt: Apt update settings. Use this setting to override the default
	// `apt` patch rules.
	Apt *AptSettings `json:"apt,omitempty"`

	// Goo: Goo update settings. Use this setting to override the default
	// `goo` patch rules.
	Goo *GooSettings `json:"goo,omitempty"`

	// PostStep: The `ExecStep` to run after the patch update.
	PostStep *ExecStep `json:"postStep,omitempty"`

	// PreStep: The `ExecStep` to run before the patch update.
	PreStep *ExecStep `json:"preStep,omitempty"`

	// RebootConfig: Post-patch reboot settings.
	//
	// Possible values:
	//   "REBOOT_CONFIG_UNSPECIFIED" - The default behavior is DEFAULT.
	//   "DEFAULT" - The agent decides if a reboot is necessary by checking
	// signals such as registry keys on Windows or
	// `/var/run/reboot-required` on APT based systems. On RPM based
	// systems, a set of core system package install times are compared with
	// system boot time.
	//   "ALWAYS" - Always reboot the machine after the update completes.
	//   "NEVER" - Never reboot the machine after the update completes.
	RebootConfig string `json:"rebootConfig,omitempty"`

	// WindowsUpdate: Windows update settings. Use this override the default
	// windows patch rules.
	WindowsUpdate *WindowsUpdateSettings `json:"windowsUpdate,omitempty"`

	// Yum: Yum update settings. Use this setting to override the default
	// `yum` patch rules.
	Yum *YumSettings `json:"yum,omitempty"`

	// Zypper: Zypper update settings. Use this setting to override the
	// default `zypper` patch rules.
	Zypper *ZypperSettings `json:"zypper,omitempty"`

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

// PatchDeployment: Patch deployments are configurations that individual
// patch jobs use to complete a patch. These configurations include
// instance filter, package repository settings, and a schedule. For
// more information about creating and managing patch deployments, see
// [Scheduling patch
// jobs](https://cloud.google.com/compute/docs/os-patch-management/schedu
// le-patch-jobs).
type PatchDeployment struct {
	// CreateTime: Output only. Time the patch deployment was created.
	// Timestamp is in [RFC3339](https://www.ietf.org/rfc/rfc3339.txt) text
	// format.
	CreateTime string `json:"createTime,omitempty"`

	// Description: Optional. Description of the patch deployment. Length of
	// the description is limited to 1024 characters.
	Description string `json:"description,omitempty"`

	// Duration: Optional. Duration of the patch. After the duration ends,
	// the patch times out.
	Duration string `json:"duration,omitempty"`

	// InstanceFilter: Required. VM instances to patch.
	InstanceFilter *PatchInstanceFilter `json:"instanceFilter,omitempty"`

	// LastExecuteTime: Output only. The last time a patch job was started
	// by this deployment. Timestamp is in
	// [RFC3339](https://www.ietf.org/rfc/rfc3339.txt) text format.
	LastExecuteTime string `json:"lastExecuteTime,omitempty"`

	// Name: Unique name for the patch deployment resource in a project. The
	// patch deployment name is in the form:
	// `projects/{project_id}/patchDeployments/{patch_deployment_id}`. This
	// field is ignored when you create a new patch deployment.
	Name string `json:"name,omitempty"`

	// OneTimeSchedule: Required. Schedule a one-time execution.
	OneTimeSchedule *OneTimeSchedule `json:"oneTimeSchedule,omitempty"`

	// PatchConfig: Optional. Patch configuration that is applied.
	PatchConfig *PatchConfig `json:"patchConfig,omitempty"`

	// RecurringSchedule: Required. Schedule recurring executions.
	RecurringSchedule *RecurringSchedule `json:"recurringSchedule,omitempty"`

	// Rollout: Optional. Rollout strategy of the patch job.
	Rollout *PatchRollout `json:"rollout,omitempty"`

	// UpdateTime: Output only. Time the patch deployment was last updated.
	// Timestamp is in [RFC3339](https://www.ietf.org/rfc/rfc3339.txt) text
	// format.
	UpdateTime string `json:"updateTime,omitempty"`

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

	// 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 *PatchDeployment) MarshalJSON() ([]byte, error) {
	type NoMethod PatchDeployment
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// PatchInstanceFilter: A filter to target VM instances for patching.
// The targeted VMs must meet all criteria specified. So if both labels
// and zones are specified, the patch job targets only VMs with those
// labels and in those zones.
type PatchInstanceFilter struct {
	// All: Target all VM instances in the project. If true, no other
	// criteria is permitted.
	All bool `json:"all,omitempty"`

	// GroupLabels: Targets VM instances matching at least one of these
	// label sets. This allows targeting of disparate groups, for example
	// "env=prod or env=staging".
	GroupLabels []*PatchInstanceFilterGroupLabel `json:"groupLabels,omitempty"`

	// InstanceNamePrefixes: Targets VMs whose name starts with one of these
	// prefixes. Similar to labels, this is another way to group VMs when
	// targeting configs, for example prefix="prod-".
	InstanceNamePrefixes []string `json:"instanceNamePrefixes,omitempty"`

	// Instances: Targets any of the VM instances specified. Instances are
	// specified by their URI in the form
	// `zones/[ZONE]/instances/[INSTANCE_NAME]`,
	// `projects/[PROJECT_ID]/zones/[ZONE]/instances/[INSTANCE_NAME]`, or
	// `https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/[ZO
	// NE]/instances/[INSTANCE_NAME]`
	Instances []string `json:"instances,omitempty"`

	// Zones: Targets VM instances in ANY of these zones. Leave empty to
	// target VM instances in any zone.
	Zones []string `json:"zones,omitempty"`

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

// PatchInstanceFilterGroupLabel: Represents a group of VMs that can be
// identified as having all these labels, for example "env=prod and
// app=web".
type PatchInstanceFilterGroupLabel struct {
	// Labels: Compute Engine instance labels that must be present for a VM
	// instance to be targeted by this filter.
	Labels map[string]string `json:"labels,omitempty"`

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

// PatchJob: A high level representation of a patch job that is either
// in progress or has completed. Instance details are not included in
// the job. To paginate through instance details, use
// `ListPatchJobInstanceDetails`. For more information about patch jobs,
// see [Creating patch
// jobs](https://cloud.google.com/compute/docs/os-patch-management/create
// -patch-job).
type PatchJob struct {
	// CreateTime: Time this patch job was created.
	CreateTime string `json:"createTime,omitempty"`

	// Description: Description of the patch job. Length of the description
	// is limited to 1024 characters.
	Description string `json:"description,omitempty"`

	// DisplayName: Display name for this patch job. This is not a unique
	// identifier.
	DisplayName string `json:"displayName,omitempty"`

	// DryRun: If this patch job is a dry run, the agent reports that it has
	// finished without running any updates on the VM instance.
	DryRun bool `json:"dryRun,omitempty"`

	// Duration: Duration of the patch job. After the duration ends, the
	// patch job times out.
	Duration string `json:"duration,omitempty"`

	// ErrorMessage: If this patch job failed, this message provides
	// information about the failure.
	ErrorMessage string `json:"errorMessage,omitempty"`

	// InstanceDetailsSummary: Summary of instance details.
	InstanceDetailsSummary *PatchJobInstanceDetailsSummary `json:"instanceDetailsSummary,omitempty"`

	// InstanceFilter: Instances to patch.
	InstanceFilter *PatchInstanceFilter `json:"instanceFilter,omitempty"`

	// Name: Unique identifier for this patch job in the form
	// `projects/*/patchJobs/*`
	Name string `json:"name,omitempty"`

	// PatchConfig: Patch configuration being applied.
	PatchConfig *PatchConfig `json:"patchConfig,omitempty"`

	// PatchDeployment: Output only. Name of the patch deployment that
	// created this patch job.
	PatchDeployment string `json:"patchDeployment,omitempty"`

	// PercentComplete: Reflects the overall progress of the patch job in
	// the range of 0.0 being no progress to 100.0 being complete.
	PercentComplete float64 `json:"percentComplete,omitempty"`

	// Rollout: Rollout strategy being applied.
	Rollout *PatchRollout `json:"rollout,omitempty"`

	// State: The current state of the PatchJob.
	//
	// Possible values:
	//   "STATE_UNSPECIFIED" - State must be specified.
	//   "STARTED" - The patch job was successfully initiated.
	//   "INSTANCE_LOOKUP" - The patch job is looking up instances to run
	// the patch on.
	//   "PATCHING" - Instances are being patched.
	//   "SUCCEEDED" - Patch job completed successfully.
	//   "COMPLETED_WITH_ERRORS" - Patch job completed but there were
	// errors.
	//   "CANCELED" - The patch job was canceled.
	//   "TIMED_OUT" - The patch job timed out.
	State string `json:"state,omitempty"`

	// UpdateTime: Last time this patch job was updated.
	UpdateTime string `json:"updateTime,omitempty"`

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

	// 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 *PatchJob) MarshalJSON() ([]byte, error) {
	type NoMethod PatchJob
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *PatchJob) UnmarshalJSON(data []byte) error {
	type NoMethod PatchJob
	var s1 struct {
		PercentComplete gensupport.JSONFloat64 `json:"percentComplete"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.PercentComplete = float64(s1.PercentComplete)
	return nil
}

// PatchJobInstanceDetails: Patch details for a VM instance. For more
// information about reviewing VM instance details, see [Listing all VM
// instance details for a specific patch
// job](https://cloud.google.com/compute/docs/os-patch-management/manage-
// patch-jobs#list-instance-details).
type PatchJobInstanceDetails struct {
	// AttemptCount: The number of times the agent that the agent attempts
	// to apply the patch.
	AttemptCount int64 `json:"attemptCount,omitempty,string"`

	// FailureReason: If the patch fails, this field provides the reason.
	FailureReason string `json:"failureReason,omitempty"`

	// InstanceSystemId: The unique identifier for the instance. This
	// identifier is defined by the server.
	InstanceSystemId string `json:"instanceSystemId,omitempty"`

	// Name: The instance name in the form `projects/*/zones/*/instances/*`
	Name string `json:"name,omitempty"`

	// State: Current state of instance patch.
	//
	// Possible values:
	//   "PATCH_STATE_UNSPECIFIED" - Unspecified.
	//   "PENDING" - The instance is not yet notified.
	//   "INACTIVE" - Instance is inactive and cannot be patched.
	//   "NOTIFIED" - The instance is notified that it should be patched.
	//   "STARTED" - The instance has started the patching process.
	//   "DOWNLOADING_PATCHES" - The instance is downloading patches.
	//   "APPLYING_PATCHES" - The instance is applying patches.
	//   "REBOOTING" - The instance is rebooting.
	//   "SUCCEEDED" - The instance has completed applying patches.
	//   "SUCCEEDED_REBOOT_REQUIRED" - The instance has completed applying
	// patches but a reboot is required.
	//   "FAILED" - The instance has failed to apply the patch.
	//   "ACKED" - The instance acked the notification and will start
	// shortly.
	//   "TIMED_OUT" - The instance exceeded the time out while applying the
	// patch.
	//   "RUNNING_PRE_PATCH_STEP" - The instance is running the pre-patch
	// step.
	//   "RUNNING_POST_PATCH_STEP" - The instance is running the post-patch
	// step.
	//   "NO_AGENT_DETECTED" - The service could not detect the presence of
	// the agent. Check to ensure that the agent is installed, running, and
	// able to communicate with the service.
	State string `json:"state,omitempty"`

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

// PatchJobInstanceDetailsSummary: A summary of the current patch state
// across all instances that this patch job affects. Contains counts of
// instances in different states. These states map to
// `InstancePatchState`. List patch job instance details to see the
// specific states of each instance.
type PatchJobInstanceDetailsSummary struct {
	// AckedInstanceCount: Number of instances that have acked and will
	// start shortly.
	AckedInstanceCount int64 `json:"ackedInstanceCount,omitempty,string"`

	// ApplyingPatchesInstanceCount: Number of instances that are applying
	// patches.
	ApplyingPatchesInstanceCount int64 `json:"applyingPatchesInstanceCount,omitempty,string"`

	// DownloadingPatchesInstanceCount: Number of instances that are
	// downloading patches.
	DownloadingPatchesInstanceCount int64 `json:"downloadingPatchesInstanceCount,omitempty,string"`

	// FailedInstanceCount: Number of instances that failed.
	FailedInstanceCount int64 `json:"failedInstanceCount,omitempty,string"`

	// InactiveInstanceCount: Number of instances that are inactive.
	InactiveInstanceCount int64 `json:"inactiveInstanceCount,omitempty,string"`

	// NoAgentDetectedInstanceCount: Number of instances that do not appear
	// to be running the agent. Check to ensure that the agent is installed,
	// running, and able to communicate with the service.
	NoAgentDetectedInstanceCount int64 `json:"noAgentDetectedInstanceCount,omitempty,string"`

	// NotifiedInstanceCount: Number of instances notified about patch job.
	NotifiedInstanceCount int64 `json:"notifiedInstanceCount,omitempty,string"`

	// PendingInstanceCount: Number of instances pending patch job.
	PendingInstanceCount int64 `json:"pendingInstanceCount,omitempty,string"`

	// PostPatchStepInstanceCount: Number of instances that are running the
	// post-patch step.
	PostPatchStepInstanceCount int64 `json:"postPatchStepInstanceCount,omitempty,string"`

	// PrePatchStepInstanceCount: Number of instances that are running the
	// pre-patch step.
	PrePatchStepInstanceCount int64 `json:"prePatchStepInstanceCount,omitempty,string"`

	// RebootingInstanceCount: Number of instances rebooting.
	RebootingInstanceCount int64 `json:"rebootingInstanceCount,omitempty,string"`

	// StartedInstanceCount: Number of instances that have started.
	StartedInstanceCount int64 `json:"startedInstanceCount,omitempty,string"`

	// SucceededInstanceCount: Number of instances that have completed
	// successfully.
	SucceededInstanceCount int64 `json:"succeededInstanceCount,omitempty,string"`

	// SucceededRebootRequiredInstanceCount: Number of instances that
	// require reboot.
	SucceededRebootRequiredInstanceCount int64 `json:"succeededRebootRequiredInstanceCount,omitempty,string"`

	// TimedOutInstanceCount: Number of instances that exceeded the time out
	// while applying the patch.
	TimedOutInstanceCount int64 `json:"timedOutInstanceCount,omitempty,string"`

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

// PatchRollout: Patch rollout configuration specifications. Contains
// details on the concurrency control when applying patch(es) to all
// targeted VMs.
type PatchRollout struct {
	// DisruptionBudget: The maximum number (or percentage) of VMs per zone
	// to disrupt at any given moment. The number of VMs calculated from
	// multiplying the percentage by the total number of VMs in a zone is
	// rounded up. During patching, a VM is considered disrupted from the
	// time the agent is notified to begin until patching has completed.
	// This disruption time includes the time to complete reboot and any
	// post-patch steps. A VM contributes to the disruption budget if its
	// patching operation fails either when applying the patches, running
	// pre or post patch steps, or if it fails to respond with a success
	// notification before timing out. VMs that are not running or do not
	// have an active agent do not count toward this disruption budget. For
	// zone-by-zone rollouts, if the disruption budget in a zone is
	// exceeded, the patch job stops, because continuing to the next zone
	// requires completion of the patch process in the previous zone. For
	// example, if the disruption budget has a fixed value of `10`, and 8
	// VMs fail to patch in the current zone, the patch job continues to
	// patch 2 VMs at a time until the zone is completed. When that zone is
	// completed successfully, patching begins with 10 VMs at a time in the
	// next zone. If 10 VMs in the next zone fail to patch, the patch job
	// stops.
	DisruptionBudget *FixedOrPercent `json:"disruptionBudget,omitempty"`

	// Mode: Mode of the patch rollout.
	//
	// Possible values:
	//   "MODE_UNSPECIFIED" - Mode must be specified.
	//   "ZONE_BY_ZONE" - Patches are applied one zone at a time. The patch
	// job begins in the region with the lowest number of targeted VMs.
	// Within the region, patching begins in the zone with the lowest number
	// of targeted VMs. If multiple regions (or zones within a region) have
	// the same number of targeted VMs, a tie-breaker is achieved by sorting
	// the regions or zones in alphabetical order.
	//   "CONCURRENT_ZONES" - Patches are applied to VMs in all zones at the
	// same time.
	Mode string `json:"mode,omitempty"`

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

// RecurringSchedule: Sets the time for recurring patch deployments.
type RecurringSchedule struct {
	// EndTime: Optional. The end time at which a recurring patch deployment
	// schedule is no longer active.
	EndTime string `json:"endTime,omitempty"`

	// Frequency: Required. The frequency unit of this recurring schedule.
	//
	// Possible values:
	//   "FREQUENCY_UNSPECIFIED" - Invalid. A frequency must be specified.
	//   "WEEKLY" - Indicates that the frequency should be expressed in
	// terms of weeks.
	//   "MONTHLY" - Indicates that the frequency should be expressed in
	// terms of months.
	Frequency string `json:"frequency,omitempty"`

	// LastExecuteTime: Output only. The time the last patch job ran
	// successfully.
	LastExecuteTime string `json:"lastExecuteTime,omitempty"`

	// Monthly: Required. Schedule with monthly executions.
	Monthly *MonthlySchedule `json:"monthly,omitempty"`

	// NextExecuteTime: Output only. The time the next patch job is
	// scheduled to run.
	NextExecuteTime string `json:"nextExecuteTime,omitempty"`

	// StartTime: Optional. The time that the recurring schedule becomes
	// effective. Defaults to `create_time` of the patch deployment.
	StartTime string `json:"startTime,omitempty"`

	// TimeOfDay: Required. Time of the day to run a recurring deployment.
	TimeOfDay *TimeOfDay `json:"timeOfDay,omitempty"`

	// TimeZone: Required. Defines the time zone that `time_of_day` is
	// relative to. The rules for daylight saving time are determined by the
	// chosen time zone.
	TimeZone *TimeZone `json:"timeZone,omitempty"`

	// Weekly: Required. Schedule with weekly executions.
	Weekly *WeeklySchedule `json:"weekly,omitempty"`

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

// SoftwareRecipe: A software recipe is a set of instructions for
// installing and configuring a piece of software. It consists of a set
// of artifacts that are downloaded, and a set of steps that install,
// configure, and/or update the software. Recipes support installing and
// updating software from artifacts in the following formats: Zip
// archive, Tar archive, Windows MSI, Debian package, and RPM package.
// Additionally, recipes support executing a script (either defined in a
// file or directly in this api) in bash, sh, cmd, and powershell.
// Updating a software recipe If a recipe is assigned to an instance and
// there is a recipe with the same name but a lower version already
// installed and the assigned state of the recipe is `UPDATED`, then the
// recipe is updated to the new version. Script Working Directories Each
// script or execution step is run in its own temporary directory which
// is deleted after completing the step.
type SoftwareRecipe struct {
	// Artifacts: Resources available to be used in the steps in the recipe.
	Artifacts []*SoftwareRecipeArtifact `json:"artifacts,omitempty"`

	// DesiredState: Default is INSTALLED. The desired state the agent
	// should maintain for this recipe. INSTALLED: The software recipe is
	// installed on the instance but won't be updated to new versions.
	// UPDATED: The software recipe is installed on the instance. The recipe
	// is updated to a higher version, if a higher version of the recipe is
	// assigned to this instance. REMOVE: Remove is unsupported for software
	// recipes and attempts to create or update a recipe to the REMOVE state
	// is rejected.
	//
	// Possible values:
	//   "DESIRED_STATE_UNSPECIFIED" - The default is to ensure the package
	// is installed.
	//   "INSTALLED" - The agent ensures that the package is installed.
	//   "UPDATED" - The agent ensures that the package is installed and
	// periodically checks for and install any updates.
	//   "REMOVED" - The agent ensures that the package is not installed and
	// uninstall it if detected.
	DesiredState string `json:"desiredState,omitempty"`

	// InstallSteps: Actions to be taken for installing this recipe. On
	// failure it stops executing steps and does not attempt another
	// installation. Any steps taken (including partially completed steps)
	// are not rolled back.
	InstallSteps []*SoftwareRecipeStep `json:"installSteps,omitempty"`

	// Name: Required. Unique identifier for the recipe. Only one recipe
	// with a given name is installed on an instance. Names are also used to
	// identify resources which helps to determine whether guest policies
	// have conflicts. This means that requests to create multiple recipes
	// with the same name and version are rejected since they could
	// potentially have conflicting assignments.
	Name string `json:"name,omitempty"`

	// UpdateSteps: Actions to be taken for updating this recipe. On failure
	// it stops executing steps and does not attempt another update for this
	// recipe. Any steps taken (including partially completed steps) are not
	// rolled back.
	UpdateSteps []*SoftwareRecipeStep `json:"updateSteps,omitempty"`

	// Version: The version of this software recipe. Version can be up to 4
	// period separated numbers (e.g. 12.34.56.78).
	Version string `json:"version,omitempty"`

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

// SoftwareRecipeArtifact: Specifies a resource to be used in the
// recipe.
type SoftwareRecipeArtifact struct {
	// AllowInsecure: Defaults to false. When false, recipes are subject to
	// validations based on the artifact type: Remote: A checksum must be
	// specified, and only protocols with transport-layer security are
	// permitted. GCS: An object generation number must be specified.
	AllowInsecure bool `json:"allowInsecure,omitempty"`

	// Gcs: A Google Cloud Storage artifact.
	Gcs *SoftwareRecipeArtifactGcs `json:"gcs,omitempty"`

	// Id: Required. Id of the artifact, which the installation and update
	// steps of this recipe can reference. Artifacts in a recipe cannot have
	// the same id.
	Id string `json:"id,omitempty"`

	// Remote: A generic remote artifact.
	Remote *SoftwareRecipeArtifactRemote `json:"remote,omitempty"`

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

// SoftwareRecipeArtifactGcs: Specifies an artifact available as a
// Google Cloud Storage object.
type SoftwareRecipeArtifactGcs struct {
	// Bucket: Bucket of the Google Cloud Storage object. Given an example
	// URL: `https://storage.googleapis.com/my-bucket/foo/bar#1234567` this
	// value would be `my-bucket`.
	Bucket string `json:"bucket,omitempty"`

	// Generation: Must be provided if allow_insecure is false. Generation
	// number of the Google Cloud Storage object.
	// `https://storage.googleapis.com/my-bucket/foo/bar#1234567` this value
	// would be `1234567`.
	Generation int64 `json:"generation,omitempty,string"`

	// Object: Name of the Google Cloud Storage object. As specified [here]
	// (https://cloud.google.com/storage/docs/naming#objectnames) Given an
	// example URL:
	// `https://storage.googleapis.com/my-bucket/foo/bar#1234567` this value
	// would be `foo/bar`.
	Object string `json:"object,omitempty"`

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

// SoftwareRecipeArtifactRemote: Specifies an artifact available via
// some URI.
type SoftwareRecipeArtifactRemote struct {
	// Checksum: Must be provided if `allow_insecure` is `false`. SHA256
	// checksum in hex format, to compare to the checksum of the artifact.
	// If the checksum is not empty and it doesn't match the artifact then
	// the recipe installation fails before running any of the steps.
	Checksum string `json:"checksum,omitempty"`

	// Uri: URI from which to fetch the object. It should contain both the
	// protocol and path following the format {protocol}://{location}.
	Uri string `json:"uri,omitempty"`

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

// SoftwareRecipeStep: An action that can be taken as part of installing
// or updating a recipe.
type SoftwareRecipeStep struct {
	// ArchiveExtraction: Extracts an archive into the specified directory.
	ArchiveExtraction *SoftwareRecipeStepExtractArchive `json:"archiveExtraction,omitempty"`

	// DpkgInstallation: Installs a deb file via dpkg.
	DpkgInstallation *SoftwareRecipeStepInstallDpkg `json:"dpkgInstallation,omitempty"`

	// FileCopy: Copies a file onto the instance.
	FileCopy *SoftwareRecipeStepCopyFile `json:"fileCopy,omitempty"`

	// FileExec: Executes an artifact or local file.
	FileExec *SoftwareRecipeStepExecFile `json:"fileExec,omitempty"`

	// MsiInstallation: Installs an MSI file.
	MsiInstallation *SoftwareRecipeStepInstallMsi `json:"msiInstallation,omitempty"`

	// RpmInstallation: Installs an rpm file via the rpm utility.
	RpmInstallation *SoftwareRecipeStepInstallRpm `json:"rpmInstallation,omitempty"`

	// ScriptRun: Runs commands in a shell.
	ScriptRun *SoftwareRecipeStepRunScript `json:"scriptRun,omitempty"`

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

// SoftwareRecipeStepCopyFile: Copies the artifact to the specified path
// on the instance.
type SoftwareRecipeStepCopyFile struct {
	// ArtifactId: Required. The id of the relevant artifact in the recipe.
	ArtifactId string `json:"artifactId,omitempty"`

	// Destination: Required. The absolute path on the instance to put the
	// file.
	Destination string `json:"destination,omitempty"`

	// Overwrite: Whether to allow this step to overwrite existing files. If
	// this is false and the file already exists the file is not overwritten
	// and the step is considered a success. Defaults to false.
	Overwrite bool `json:"overwrite,omitempty"`

	// Permissions: Consists of three octal digits which represent, in
	// order, the permissions of the owner, group, and other users for the
	// file (similarly to the numeric mode used in the linux chmod utility).
	// Each digit represents a three bit number with the 4 bit corresponding
	// to the read permissions, the 2 bit corresponds to the write bit, and
	// the one bit corresponds to the execute permission. Default behavior
	// is 755. Below are some examples of permissions and their associated
	// values: read, write, and execute: 7 read and execute: 5 read and
	// write: 6 read only: 4
	Permissions string `json:"permissions,omitempty"`

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

// SoftwareRecipeStepExecFile: Executes an artifact or local file.
type SoftwareRecipeStepExecFile struct {
	// AllowedExitCodes: Defaults to [0]. A list of possible return values
	// that the program can return to indicate a success.
	AllowedExitCodes []int64 `json:"allowedExitCodes,omitempty"`

	// Args: Arguments to be passed to the provided executable.
	Args []string `json:"args,omitempty"`

	// ArtifactId: The id of the relevant artifact in the recipe.
	ArtifactId string `json:"artifactId,omitempty"`

	// LocalPath: The absolute path of the file on the local filesystem.
	LocalPath string `json:"localPath,omitempty"`

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

// SoftwareRecipeStepExtractArchive: Extracts an archive of the type
// specified in the specified directory.
type SoftwareRecipeStepExtractArchive struct {
	// ArtifactId: Required. The id of the relevant artifact in the recipe.
	ArtifactId string `json:"artifactId,omitempty"`

	// Destination: Directory to extract archive to. Defaults to `/` on
	// Linux or `C:\` on Windows.
	Destination string `json:"destination,omitempty"`

	// Type: Required. The type of the archive to extract.
	//
	// Possible values:
	//   "ARCHIVE_TYPE_UNSPECIFIED" - Indicates that the archive type isn't
	// specified.
	//   "TAR" - Indicates that the archive is a tar archive with no
	// encryption.
	//   "TAR_GZIP" - Indicates that the archive is a tar archive with gzip
	// encryption.
	//   "TAR_BZIP" - Indicates that the archive is a tar archive with bzip
	// encryption.
	//   "TAR_LZMA" - Indicates that the archive is a tar archive with lzma
	// encryption.
	//   "TAR_XZ" - Indicates that the archive is a tar archive with xz
	// encryption.
	//   "ZIP" - Indicates that the archive is a zip archive.
	Type string `json:"type,omitempty"`

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

// SoftwareRecipeStepInstallDpkg: Installs a deb via dpkg.
type SoftwareRecipeStepInstallDpkg struct {
	// ArtifactId: Required. The id of the relevant artifact in the recipe.
	ArtifactId string `json:"artifactId,omitempty"`

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

// SoftwareRecipeStepInstallMsi: Installs an MSI file.
type SoftwareRecipeStepInstallMsi struct {
	// AllowedExitCodes: Return codes that indicate that the software
	// installed or updated successfully. Behaviour defaults to [0]
	AllowedExitCodes []int64 `json:"allowedExitCodes,omitempty"`

	// ArtifactId: Required. The id of the relevant artifact in the recipe.
	ArtifactId string `json:"artifactId,omitempty"`

	// Flags: The flags to use when installing the MSI defaults to ["/i"]
	// (i.e. the install flag).
	Flags []string `json:"flags,omitempty"`

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

// SoftwareRecipeStepInstallRpm: Installs an rpm file via the rpm
// utility.
type SoftwareRecipeStepInstallRpm struct {
	// ArtifactId: Required. The id of the relevant artifact in the recipe.
	ArtifactId string `json:"artifactId,omitempty"`

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

// SoftwareRecipeStepRunScript: Runs a script through an interpreter.
type SoftwareRecipeStepRunScript struct {
	// AllowedExitCodes: Return codes that indicate that the software
	// installed or updated successfully. Behaviour defaults to [0]
	AllowedExitCodes []int64 `json:"allowedExitCodes,omitempty"`

	// Interpreter: The script interpreter to use to run the script. If no
	// interpreter is specified the script is executed directly, which
	// likely only succeed for scripts with [shebang
	// lines](https://en.wikipedia.org/wiki/Shebang_\(Unix\)).
	//
	// Possible values:
	//   "INTERPRETER_UNSPECIFIED" - Default value for ScriptType.
	//   "SHELL" - Indicates that the script is run with `/bin/sh` on Linux
	// and `cmd` on windows.
	//   "POWERSHELL" - Indicates that the script is run with powershell.
	Interpreter string `json:"interpreter,omitempty"`

	// Script: Required. The shell script to be executed.
	Script string `json:"script,omitempty"`

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

// TimeOfDay: Represents a time of day. The date and time zone are
// either not significant or are specified elsewhere. An API may choose
// to allow leap seconds. Related types are google.type.Date and
// `google.protobuf.Timestamp`.
type TimeOfDay struct {
	// Hours: Hours of day in 24 hour format. Should be from 0 to 23. An API
	// may choose to allow the value "24:00:00" for scenarios like business
	// closing time.
	Hours int64 `json:"hours,omitempty"`

	// Minutes: Minutes of hour of day. Must be from 0 to 59.
	Minutes int64 `json:"minutes,omitempty"`

	// Nanos: Fractions of seconds in nanoseconds. Must be from 0 to
	// 999,999,999.
	Nanos int64 `json:"nanos,omitempty"`

	// Seconds: Seconds of minutes of the time. Must normally be from 0 to
	// 59. An API may allow the value 60 if it allows leap-seconds.
	Seconds int64 `json:"seconds,omitempty"`

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

// TimeZone: Represents a time zone from the [IANA Time Zone
// Database](https://www.iana.org/time-zones).
type TimeZone struct {
	// Id: IANA Time Zone Database time zone, e.g. "America/New_York".
	Id string `json:"id,omitempty"`

	// Version: Optional. IANA Time Zone Database version number, e.g.
	// "2019a".
	Version string `json:"version,omitempty"`

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

// WeekDayOfMonth: Represents one week day in a month. An example is
// "the 4th Sunday".
type WeekDayOfMonth struct {
	// DayOfWeek: Required. A day of the week.
	//
	// Possible values:
	//   "DAY_OF_WEEK_UNSPECIFIED" - The day of the week is unspecified.
	//   "MONDAY" - Monday
	//   "TUESDAY" - Tuesday
	//   "WEDNESDAY" - Wednesday
	//   "THURSDAY" - Thursday
	//   "FRIDAY" - Friday
	//   "SATURDAY" - Saturday
	//   "SUNDAY" - Sunday
	DayOfWeek string `json:"dayOfWeek,omitempty"`

	// WeekOrdinal: Required. Week number in a month. 1-4 indicates the 1st
	// to 4th week of the month. -1 indicates the last week of the month.
	WeekOrdinal int64 `json:"weekOrdinal,omitempty"`

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

// WeeklySchedule: Represents a weekly schedule.
type WeeklySchedule struct {
	// DayOfWeek: Required. Day of the week.
	//
	// Possible values:
	//   "DAY_OF_WEEK_UNSPECIFIED" - The day of the week is unspecified.
	//   "MONDAY" - Monday
	//   "TUESDAY" - Tuesday
	//   "WEDNESDAY" - Wednesday
	//   "THURSDAY" - Thursday
	//   "FRIDAY" - Friday
	//   "SATURDAY" - Saturday
	//   "SUNDAY" - Sunday
	DayOfWeek string `json:"dayOfWeek,omitempty"`

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

// WindowsUpdateSettings: Windows patching is performed using the
// Windows Update Agent.
type WindowsUpdateSettings struct {
	// Classifications: Only apply updates of these windows update
	// classifications. If empty, all updates are applied.
	//
	// Possible values:
	//   "CLASSIFICATION_UNSPECIFIED" - Invalid. If classifications are
	// included, they must be specified.
	//   "CRITICAL" - "A widely released fix for a specific problem that
	// addresses a critical, non-security-related bug." [1]
	//   "SECURITY" - "A widely released fix for a product-specific,
	// security-related vulnerability. Security vulnerabilities are rated by
	// their severity. The severity rating is indicated in the Microsoft
	// security bulletin as critical, important, moderate, or low." [1]
	//   "DEFINITION" - "A widely released and frequent software update that
	// contains additions to a product's definition database. Definition
	// databases are often used to detect objects that have specific
	// attributes, such as malicious code, phishing websites, or junk mail."
	// [1]
	//   "DRIVER" - "Software that controls the input and output of a
	// device." [1]
	//   "FEATURE_PACK" - "New product functionality that is first
	// distributed outside the context of a product release and that is
	// typically included in the next full product release." [1]
	//   "SERVICE_PACK" - "A tested, cumulative set of all hotfixes,
	// security updates, critical updates, and updates. Additionally,
	// service packs may contain additional fixes for problems that are
	// found internally since the release of the product. Service packs my
	// also contain a limited number of customer-requested design changes or
	// features." [1]
	//   "TOOL" - "A utility or feature that helps complete a task or set of
	// tasks." [1]
	//   "UPDATE_ROLLUP" - "A tested, cumulative set of hotfixes, security
	// updates, critical updates, and updates that are packaged together for
	// easy deployment. A rollup generally targets a specific area, such as
	// security, or a component of a product, such as Internet Information
	// Services (IIS)." [1]
	//   "UPDATE" - "A widely released fix for a specific problem. An update
	// addresses a noncritical, non-security-related bug." [1]
	Classifications []string `json:"classifications,omitempty"`

	// Excludes: List of KBs to exclude from update.
	Excludes []string `json:"excludes,omitempty"`

	// ExclusivePatches: An exclusive list of kbs to be updated. These are
	// the only patches that will be updated. This field must not be used
	// with other patch configurations.
	ExclusivePatches []string `json:"exclusivePatches,omitempty"`

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

// YumRepository: Represents a single Yum package repository. This
// repository is added to a repo file that is stored at
// `/etc/yum.repos.d/google_osconfig.repo`.
type YumRepository struct {
	// BaseUrl: Required. The location of the repository directory.
	BaseUrl string `json:"baseUrl,omitempty"`

	// DisplayName: The display name of the repository.
	DisplayName string `json:"displayName,omitempty"`

	// GpgKeys: URIs of GPG keys.
	GpgKeys []string `json:"gpgKeys,omitempty"`

	// Id: Required. A one word, unique name for this repository. This is
	// the `repo id` in the Yum config file and also the `display_name` if
	// `display_name` is omitted. This id is also used as the unique
	// identifier when checking for guest policy conflicts.
	Id string `json:"id,omitempty"`

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

// YumSettings: Yum patching is performed by executing `yum update`.
// Additional options can be set to control how this is executed. Note
// that not all settings are supported on all platforms.
type YumSettings struct {
	// Excludes: List of packages to exclude from update. These packages are
	// excluded by using the yum `--exclude` flag.
	Excludes []string `json:"excludes,omitempty"`

	// ExclusivePackages: An exclusive list of packages to be updated. These
	// are the only packages that will be updated. If these packages are not
	// installed, they will be ignored. This field must not be specified
	// with any other patch configuration fields.
	ExclusivePackages []string `json:"exclusivePackages,omitempty"`

	// Minimal: Will cause patch to run `yum update-minimal` instead.
	Minimal bool `json:"minimal,omitempty"`

	// Security: Adds the `--security` flag to `yum update`. Not supported
	// on all platforms.
	Security bool `json:"security,omitempty"`

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

// ZypperRepository: Represents a single Zypper package repository. This
// repository is added to a repo file that is stored at
// `/etc/zypp/repos.d/google_osconfig.repo`.
type ZypperRepository struct {
	// BaseUrl: Required. The location of the repository directory.
	BaseUrl string `json:"baseUrl,omitempty"`

	// DisplayName: The display name of the repository.
	DisplayName string `json:"displayName,omitempty"`

	// GpgKeys: URIs of GPG keys.
	GpgKeys []string `json:"gpgKeys,omitempty"`

	// Id: Required. A one word, unique name for this repository. This is
	// the `repo id` in the zypper config file and also the `display_name`
	// if `display_name` is omitted. This id is also used as the unique
	// identifier when checking for guest policy conflicts.
	Id string `json:"id,omitempty"`

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

// ZypperSettings: Zypper patching is performed by running `zypper
// patch`. See also https://en.opensuse.org/SDB:Zypper_manual.
type ZypperSettings struct {
	// Categories: Install only patches with these categories. Common
	// categories include security, recommended, and feature.
	Categories []string `json:"categories,omitempty"`

	// Excludes: List of patches to exclude from update.
	Excludes []string `json:"excludes,omitempty"`

	// ExclusivePatches: An exclusive list of patches to be updated. These
	// are the only patches that will be installed using 'zypper patch
	// patch:' command. This field must not be used with any other patch
	// configuration fields.
	ExclusivePatches []string `json:"exclusivePatches,omitempty"`

	// Severities: Install only patches with these severities. Common
	// severities include critical, important, moderate, and low.
	Severities []string `json:"severities,omitempty"`

	// WithOptional: Adds the `--with-optional` flag to `zypper patch`.
	WithOptional bool `json:"withOptional,omitempty"`

	// WithUpdate: Adds the `--with-update` flag, to `zypper patch`.
	WithUpdate bool `json:"withUpdate,omitempty"`

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

// method id "osconfig.projects.guestPolicies.create":

type ProjectsGuestPoliciesCreateCall struct {
	s           *Service
	parent      string
	guestpolicy *GuestPolicy
	urlParams_  gensupport.URLParams
	ctx_        context.Context
	header_     http.Header
}

// Create: Create an OS Config guest policy.
func (r *ProjectsGuestPoliciesService) Create(parent string, guestpolicy *GuestPolicy) *ProjectsGuestPoliciesCreateCall {
	c := &ProjectsGuestPoliciesCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.guestpolicy = guestpolicy
	return c
}

// GuestPolicyId sets the optional parameter "guestPolicyId": Required.
// The logical name of the guest policy in the project with the
// following restrictions: * Must contain only lowercase letters,
// numbers, and hyphens. * Must start with a letter. * Must be between
// 1-63 characters. * Must end with a number or a letter. * Must be
// unique within the project.
func (c *ProjectsGuestPoliciesCreateCall) GuestPolicyId(guestPolicyId string) *ProjectsGuestPoliciesCreateCall {
	c.urlParams_.Set("guestPolicyId", guestPolicyId)
	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 *ProjectsGuestPoliciesCreateCall) Fields(s ...googleapi.Field) *ProjectsGuestPoliciesCreateCall {
	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 *ProjectsGuestPoliciesCreateCall) Context(ctx context.Context) *ProjectsGuestPoliciesCreateCall {
	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 *ProjectsGuestPoliciesCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsGuestPoliciesCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20201002")
	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.guestpolicy)
	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, "v1beta/{+parent}/guestPolicies")
	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 "osconfig.projects.guestPolicies.create" call.
// Exactly one of *GuestPolicy or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *GuestPolicy.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 *ProjectsGuestPoliciesCreateCall) Do(opts ...googleapi.CallOption) (*GuestPolicy, 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 := &GuestPolicy{
		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": "Create an OS Config guest policy.",
	//   "flatPath": "v1beta/projects/{projectsId}/guestPolicies",
	//   "httpMethod": "POST",
	//   "id": "osconfig.projects.guestPolicies.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "guestPolicyId": {
	//       "description": "Required. The logical name of the guest policy in the project with the following restrictions: * Must contain only lowercase letters, numbers, and hyphens. * Must start with a letter. * Must be between 1-63 characters. * Must end with a number or a letter. * Must be unique within the project.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. The resource name of the parent using one of the following forms: `projects/{project_number}`.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta/{+parent}/guestPolicies",
	//   "request": {
	//     "$ref": "GuestPolicy"
	//   },
	//   "response": {
	//     "$ref": "GuestPolicy"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "osconfig.projects.guestPolicies.delete":

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

// Delete: Delete an OS Config guest policy.
func (r *ProjectsGuestPoliciesService) Delete(name string) *ProjectsGuestPoliciesDeleteCall {
	c := &ProjectsGuestPoliciesDeleteCall{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 *ProjectsGuestPoliciesDeleteCall) Fields(s ...googleapi.Field) *ProjectsGuestPoliciesDeleteCall {
	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 *ProjectsGuestPoliciesDeleteCall) Context(ctx context.Context) *ProjectsGuestPoliciesDeleteCall {
	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 *ProjectsGuestPoliciesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsGuestPoliciesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20201002")
	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, "v1beta/{+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 "osconfig.projects.guestPolicies.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 *ProjectsGuestPoliciesDeleteCall) 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": "Delete an OS Config guest policy.",
	//   "flatPath": "v1beta/projects/{projectsId}/guestPolicies/{guestPoliciesId}",
	//   "httpMethod": "DELETE",
	//   "id": "osconfig.projects.guestPolicies.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The resource name of the guest policy using one of the following forms: `projects/{project_number}/guestPolicies/{guest_policy_id}`.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/guestPolicies/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta/{+name}",
	//   "response": {
	//     "$ref": "Empty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "osconfig.projects.guestPolicies.get":

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

// Get: Get an OS Config guest policy.
func (r *ProjectsGuestPoliciesService) Get(name string) *ProjectsGuestPoliciesGetCall {
	c := &ProjectsGuestPoliciesGetCall{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 *ProjectsGuestPoliciesGetCall) Fields(s ...googleapi.Field) *ProjectsGuestPoliciesGetCall {
	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 *ProjectsGuestPoliciesGetCall) IfNoneMatch(entityTag string) *ProjectsGuestPoliciesGetCall {
	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 *ProjectsGuestPoliciesGetCall) Context(ctx context.Context) *ProjectsGuestPoliciesGetCall {
	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 *ProjectsGuestPoliciesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsGuestPoliciesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20201002")
	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, "v1beta/{+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 "osconfig.projects.guestPolicies.get" call.
// Exactly one of *GuestPolicy or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *GuestPolicy.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 *ProjectsGuestPoliciesGetCall) Do(opts ...googleapi.CallOption) (*GuestPolicy, 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 := &GuestPolicy{
		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": "Get an OS Config guest policy.",
	//   "flatPath": "v1beta/projects/{projectsId}/guestPolicies/{guestPoliciesId}",
	//   "httpMethod": "GET",
	//   "id": "osconfig.projects.guestPolicies.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The resource name of the guest policy using one of the following forms: `projects/{project_number}/guestPolicies/{guest_policy_id}`.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/guestPolicies/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta/{+name}",
	//   "response": {
	//     "$ref": "GuestPolicy"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "osconfig.projects.guestPolicies.list":

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

// List: Get a page of OS Config guest policies.
func (r *ProjectsGuestPoliciesService) List(parent string) *ProjectsGuestPoliciesListCall {
	c := &ProjectsGuestPoliciesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number
// of guest policies to return.
func (c *ProjectsGuestPoliciesListCall) PageSize(pageSize int64) *ProjectsGuestPoliciesListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": A pagination token
// returned from a previous call to `ListGuestPolicies` that indicates
// where this listing should continue from.
func (c *ProjectsGuestPoliciesListCall) PageToken(pageToken string) *ProjectsGuestPoliciesListCall {
	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 *ProjectsGuestPoliciesListCall) Fields(s ...googleapi.Field) *ProjectsGuestPoliciesListCall {
	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 *ProjectsGuestPoliciesListCall) IfNoneMatch(entityTag string) *ProjectsGuestPoliciesListCall {
	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 *ProjectsGuestPoliciesListCall) Context(ctx context.Context) *ProjectsGuestPoliciesListCall {
	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 *ProjectsGuestPoliciesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsGuestPoliciesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20201002")
	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, "v1beta/{+parent}/guestPolicies")
	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 "osconfig.projects.guestPolicies.list" call.
// Exactly one of *ListGuestPoliciesResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *ListGuestPoliciesResponse.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 *ProjectsGuestPoliciesListCall) Do(opts ...googleapi.CallOption) (*ListGuestPoliciesResponse, 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 := &ListGuestPoliciesResponse{
		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": "Get a page of OS Config guest policies.",
	//   "flatPath": "v1beta/projects/{projectsId}/guestPolicies",
	//   "httpMethod": "GET",
	//   "id": "osconfig.projects.guestPolicies.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "pageSize": {
	//       "description": "The maximum number of guest policies to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "A pagination token returned from a previous call to `ListGuestPolicies` that indicates where this listing should continue from.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. The resource name of the parent using one of the following forms: `projects/{project_number}`.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta/{+parent}/guestPolicies",
	//   "response": {
	//     "$ref": "ListGuestPoliciesResponse"
	//   },
	//   "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 *ProjectsGuestPoliciesListCall) Pages(ctx context.Context, f func(*ListGuestPoliciesResponse) 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 "osconfig.projects.guestPolicies.patch":

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

// Patch: Update an OS Config guest policy.
func (r *ProjectsGuestPoliciesService) Patch(name string, guestpolicy *GuestPolicy) *ProjectsGuestPoliciesPatchCall {
	c := &ProjectsGuestPoliciesPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.guestpolicy = guestpolicy
	return c
}

// UpdateMask sets the optional parameter "updateMask": Field mask that
// controls which fields of the guest policy should be updated.
func (c *ProjectsGuestPoliciesPatchCall) UpdateMask(updateMask string) *ProjectsGuestPoliciesPatchCall {
	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 *ProjectsGuestPoliciesPatchCall) Fields(s ...googleapi.Field) *ProjectsGuestPoliciesPatchCall {
	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 *ProjectsGuestPoliciesPatchCall) Context(ctx context.Context) *ProjectsGuestPoliciesPatchCall {
	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 *ProjectsGuestPoliciesPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsGuestPoliciesPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20201002")
	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.guestpolicy)
	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, "v1beta/{+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 "osconfig.projects.guestPolicies.patch" call.
// Exactly one of *GuestPolicy or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *GuestPolicy.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 *ProjectsGuestPoliciesPatchCall) Do(opts ...googleapi.CallOption) (*GuestPolicy, 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 := &GuestPolicy{
		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": "Update an OS Config guest policy.",
	//   "flatPath": "v1beta/projects/{projectsId}/guestPolicies/{guestPoliciesId}",
	//   "httpMethod": "PATCH",
	//   "id": "osconfig.projects.guestPolicies.patch",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Unique name of the resource in this project using one of the following forms: `projects/{project_number}/guestPolicies/{guest_policy_id}`.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/guestPolicies/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "updateMask": {
	//       "description": "Field mask that controls which fields of the guest policy should be updated.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta/{+name}",
	//   "request": {
	//     "$ref": "GuestPolicy"
	//   },
	//   "response": {
	//     "$ref": "GuestPolicy"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "osconfig.projects.patchDeployments.create":

type ProjectsPatchDeploymentsCreateCall struct {
	s               *Service
	parent          string
	patchdeployment *PatchDeployment
	urlParams_      gensupport.URLParams
	ctx_            context.Context
	header_         http.Header
}

// Create: Create an OS Config patch deployment.
func (r *ProjectsPatchDeploymentsService) Create(parent string, patchdeployment *PatchDeployment) *ProjectsPatchDeploymentsCreateCall {
	c := &ProjectsPatchDeploymentsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.patchdeployment = patchdeployment
	return c
}

// PatchDeploymentId sets the optional parameter "patchDeploymentId":
// Required. A name for the patch deployment in the project. When
// creating a name the following rules apply: * Must contain only
// lowercase letters, numbers, and hyphens. * Must start with a letter.
// * Must be between 1-63 characters. * Must end with a number or a
// letter. * Must be unique within the project.
func (c *ProjectsPatchDeploymentsCreateCall) PatchDeploymentId(patchDeploymentId string) *ProjectsPatchDeploymentsCreateCall {
	c.urlParams_.Set("patchDeploymentId", patchDeploymentId)
	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 *ProjectsPatchDeploymentsCreateCall) Fields(s ...googleapi.Field) *ProjectsPatchDeploymentsCreateCall {
	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 *ProjectsPatchDeploymentsCreateCall) Context(ctx context.Context) *ProjectsPatchDeploymentsCreateCall {
	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 *ProjectsPatchDeploymentsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsPatchDeploymentsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20201002")
	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.patchdeployment)
	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, "v1beta/{+parent}/patchDeployments")
	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 "osconfig.projects.patchDeployments.create" call.
// Exactly one of *PatchDeployment or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *PatchDeployment.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 *ProjectsPatchDeploymentsCreateCall) Do(opts ...googleapi.CallOption) (*PatchDeployment, 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 := &PatchDeployment{
		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": "Create an OS Config patch deployment.",
	//   "flatPath": "v1beta/projects/{projectsId}/patchDeployments",
	//   "httpMethod": "POST",
	//   "id": "osconfig.projects.patchDeployments.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. The project to apply this patch deployment to in the form `projects/*`.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "patchDeploymentId": {
	//       "description": "Required. A name for the patch deployment in the project. When creating a name the following rules apply: * Must contain only lowercase letters, numbers, and hyphens. * Must start with a letter. * Must be between 1-63 characters. * Must end with a number or a letter. * Must be unique within the project.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta/{+parent}/patchDeployments",
	//   "request": {
	//     "$ref": "PatchDeployment"
	//   },
	//   "response": {
	//     "$ref": "PatchDeployment"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "osconfig.projects.patchDeployments.delete":

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

// Delete: Delete an OS Config patch deployment.
func (r *ProjectsPatchDeploymentsService) Delete(name string) *ProjectsPatchDeploymentsDeleteCall {
	c := &ProjectsPatchDeploymentsDeleteCall{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 *ProjectsPatchDeploymentsDeleteCall) Fields(s ...googleapi.Field) *ProjectsPatchDeploymentsDeleteCall {
	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 *ProjectsPatchDeploymentsDeleteCall) Context(ctx context.Context) *ProjectsPatchDeploymentsDeleteCall {
	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 *ProjectsPatchDeploymentsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsPatchDeploymentsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20201002")
	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, "v1beta/{+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 "osconfig.projects.patchDeployments.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 *ProjectsPatchDeploymentsDeleteCall) 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": "Delete an OS Config patch deployment.",
	//   "flatPath": "v1beta/projects/{projectsId}/patchDeployments/{patchDeploymentsId}",
	//   "httpMethod": "DELETE",
	//   "id": "osconfig.projects.patchDeployments.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The resource name of the patch deployment in the form `projects/*/patchDeployments/*`.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/patchDeployments/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta/{+name}",
	//   "response": {
	//     "$ref": "Empty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "osconfig.projects.patchDeployments.get":

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

// Get: Get an OS Config patch deployment.
func (r *ProjectsPatchDeploymentsService) Get(name string) *ProjectsPatchDeploymentsGetCall {
	c := &ProjectsPatchDeploymentsGetCall{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 *ProjectsPatchDeploymentsGetCall) Fields(s ...googleapi.Field) *ProjectsPatchDeploymentsGetCall {
	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 *ProjectsPatchDeploymentsGetCall) IfNoneMatch(entityTag string) *ProjectsPatchDeploymentsGetCall {
	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 *ProjectsPatchDeploymentsGetCall) Context(ctx context.Context) *ProjectsPatchDeploymentsGetCall {
	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 *ProjectsPatchDeploymentsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsPatchDeploymentsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20201002")
	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, "v1beta/{+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 "osconfig.projects.patchDeployments.get" call.
// Exactly one of *PatchDeployment or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *PatchDeployment.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 *ProjectsPatchDeploymentsGetCall) Do(opts ...googleapi.CallOption) (*PatchDeployment, 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 := &PatchDeployment{
		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": "Get an OS Config patch deployment.",
	//   "flatPath": "v1beta/projects/{projectsId}/patchDeployments/{patchDeploymentsId}",
	//   "httpMethod": "GET",
	//   "id": "osconfig.projects.patchDeployments.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The resource name of the patch deployment in the form `projects/*/patchDeployments/*`.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/patchDeployments/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta/{+name}",
	//   "response": {
	//     "$ref": "PatchDeployment"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "osconfig.projects.patchDeployments.list":

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

// List: Get a page of OS Config patch deployments.
func (r *ProjectsPatchDeploymentsService) List(parent string) *ProjectsPatchDeploymentsListCall {
	c := &ProjectsPatchDeploymentsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number
// of patch deployments to return. Default is 100.
func (c *ProjectsPatchDeploymentsListCall) PageSize(pageSize int64) *ProjectsPatchDeploymentsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": A pagination token
// returned from a previous call to ListPatchDeployments that indicates
// where this listing should continue from.
func (c *ProjectsPatchDeploymentsListCall) PageToken(pageToken string) *ProjectsPatchDeploymentsListCall {
	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 *ProjectsPatchDeploymentsListCall) Fields(s ...googleapi.Field) *ProjectsPatchDeploymentsListCall {
	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 *ProjectsPatchDeploymentsListCall) IfNoneMatch(entityTag string) *ProjectsPatchDeploymentsListCall {
	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 *ProjectsPatchDeploymentsListCall) Context(ctx context.Context) *ProjectsPatchDeploymentsListCall {
	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 *ProjectsPatchDeploymentsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsPatchDeploymentsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20201002")
	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, "v1beta/{+parent}/patchDeployments")
	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 "osconfig.projects.patchDeployments.list" call.
// Exactly one of *ListPatchDeploymentsResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *ListPatchDeploymentsResponse.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 *ProjectsPatchDeploymentsListCall) Do(opts ...googleapi.CallOption) (*ListPatchDeploymentsResponse, 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 := &ListPatchDeploymentsResponse{
		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": "Get a page of OS Config patch deployments.",
	//   "flatPath": "v1beta/projects/{projectsId}/patchDeployments",
	//   "httpMethod": "GET",
	//   "id": "osconfig.projects.patchDeployments.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "pageSize": {
	//       "description": "Optional. The maximum number of patch deployments to return. Default is 100.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Optional. A pagination token returned from a previous call to ListPatchDeployments that indicates where this listing should continue from.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. The resource name of the parent in the form `projects/*`.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta/{+parent}/patchDeployments",
	//   "response": {
	//     "$ref": "ListPatchDeploymentsResponse"
	//   },
	//   "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 *ProjectsPatchDeploymentsListCall) Pages(ctx context.Context, f func(*ListPatchDeploymentsResponse) 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 "osconfig.projects.patchJobs.cancel":

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

// Cancel: Cancel a patch job. The patch job must be active. Canceled
// patch jobs cannot be restarted.
func (r *ProjectsPatchJobsService) Cancel(name string, cancelpatchjobrequest *CancelPatchJobRequest) *ProjectsPatchJobsCancelCall {
	c := &ProjectsPatchJobsCancelCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.cancelpatchjobrequest = cancelpatchjobrequest
	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 *ProjectsPatchJobsCancelCall) Fields(s ...googleapi.Field) *ProjectsPatchJobsCancelCall {
	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 *ProjectsPatchJobsCancelCall) Context(ctx context.Context) *ProjectsPatchJobsCancelCall {
	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 *ProjectsPatchJobsCancelCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsPatchJobsCancelCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20201002")
	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.cancelpatchjobrequest)
	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, "v1beta/{+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 "osconfig.projects.patchJobs.cancel" call.
// Exactly one of *PatchJob or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *PatchJob.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 *ProjectsPatchJobsCancelCall) Do(opts ...googleapi.CallOption) (*PatchJob, 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 := &PatchJob{
		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": "Cancel a patch job. The patch job must be active. Canceled patch jobs cannot be restarted.",
	//   "flatPath": "v1beta/projects/{projectsId}/patchJobs/{patchJobsId}:cancel",
	//   "httpMethod": "POST",
	//   "id": "osconfig.projects.patchJobs.cancel",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Name of the patch in the form `projects/*/patchJobs/*`",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/patchJobs/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta/{+name}:cancel",
	//   "request": {
	//     "$ref": "CancelPatchJobRequest"
	//   },
	//   "response": {
	//     "$ref": "PatchJob"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "osconfig.projects.patchJobs.execute":

type ProjectsPatchJobsExecuteCall struct {
	s                      *Service
	parent                 string
	executepatchjobrequest *ExecutePatchJobRequest
	urlParams_             gensupport.URLParams
	ctx_                   context.Context
	header_                http.Header
}

// Execute: Patch VM instances by creating and running a patch job.
func (r *ProjectsPatchJobsService) Execute(parent string, executepatchjobrequest *ExecutePatchJobRequest) *ProjectsPatchJobsExecuteCall {
	c := &ProjectsPatchJobsExecuteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.executepatchjobrequest = executepatchjobrequest
	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 *ProjectsPatchJobsExecuteCall) Fields(s ...googleapi.Field) *ProjectsPatchJobsExecuteCall {
	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 *ProjectsPatchJobsExecuteCall) Context(ctx context.Context) *ProjectsPatchJobsExecuteCall {
	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 *ProjectsPatchJobsExecuteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsPatchJobsExecuteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20201002")
	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.executepatchjobrequest)
	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, "v1beta/{+parent}/patchJobs:execute")
	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 "osconfig.projects.patchJobs.execute" call.
// Exactly one of *PatchJob or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *PatchJob.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 *ProjectsPatchJobsExecuteCall) Do(opts ...googleapi.CallOption) (*PatchJob, 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 := &PatchJob{
		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": "Patch VM instances by creating and running a patch job.",
	//   "flatPath": "v1beta/projects/{projectsId}/patchJobs:execute",
	//   "httpMethod": "POST",
	//   "id": "osconfig.projects.patchJobs.execute",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. The project in which to run this patch in the form `projects/*`",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta/{+parent}/patchJobs:execute",
	//   "request": {
	//     "$ref": "ExecutePatchJobRequest"
	//   },
	//   "response": {
	//     "$ref": "PatchJob"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "osconfig.projects.patchJobs.get":

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

// Get: Get the patch job. This can be used to track the progress of an
// ongoing patch job or review the details of completed jobs.
func (r *ProjectsPatchJobsService) Get(name string) *ProjectsPatchJobsGetCall {
	c := &ProjectsPatchJobsGetCall{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 *ProjectsPatchJobsGetCall) Fields(s ...googleapi.Field) *ProjectsPatchJobsGetCall {
	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 *ProjectsPatchJobsGetCall) IfNoneMatch(entityTag string) *ProjectsPatchJobsGetCall {
	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 *ProjectsPatchJobsGetCall) Context(ctx context.Context) *ProjectsPatchJobsGetCall {
	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 *ProjectsPatchJobsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsPatchJobsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20201002")
	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, "v1beta/{+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 "osconfig.projects.patchJobs.get" call.
// Exactly one of *PatchJob or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *PatchJob.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 *ProjectsPatchJobsGetCall) Do(opts ...googleapi.CallOption) (*PatchJob, 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 := &PatchJob{
		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": "Get the patch job. This can be used to track the progress of an ongoing patch job or review the details of completed jobs.",
	//   "flatPath": "v1beta/projects/{projectsId}/patchJobs/{patchJobsId}",
	//   "httpMethod": "GET",
	//   "id": "osconfig.projects.patchJobs.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Name of the patch in the form `projects/*/patchJobs/*`",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/patchJobs/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta/{+name}",
	//   "response": {
	//     "$ref": "PatchJob"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "osconfig.projects.patchJobs.list":

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

// List: Get a list of patch jobs.
func (r *ProjectsPatchJobsService) List(parent string) *ProjectsPatchJobsListCall {
	c := &ProjectsPatchJobsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Filter sets the optional parameter "filter": If provided, this field
// specifies the criteria that must be met by patch jobs to be included
// in the response. Currently, filtering is only available on the
// patch_deployment field.
func (c *ProjectsPatchJobsListCall) Filter(filter string) *ProjectsPatchJobsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number
// of instance status to return.
func (c *ProjectsPatchJobsListCall) PageSize(pageSize int64) *ProjectsPatchJobsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": A pagination token
// returned from a previous call that indicates where this listing
// should continue from.
func (c *ProjectsPatchJobsListCall) PageToken(pageToken string) *ProjectsPatchJobsListCall {
	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 *ProjectsPatchJobsListCall) Fields(s ...googleapi.Field) *ProjectsPatchJobsListCall {
	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 *ProjectsPatchJobsListCall) IfNoneMatch(entityTag string) *ProjectsPatchJobsListCall {
	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 *ProjectsPatchJobsListCall) Context(ctx context.Context) *ProjectsPatchJobsListCall {
	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 *ProjectsPatchJobsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsPatchJobsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20201002")
	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, "v1beta/{+parent}/patchJobs")
	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 "osconfig.projects.patchJobs.list" call.
// Exactly one of *ListPatchJobsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListPatchJobsResponse.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 *ProjectsPatchJobsListCall) Do(opts ...googleapi.CallOption) (*ListPatchJobsResponse, 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 := &ListPatchJobsResponse{
		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": "Get a list of patch jobs.",
	//   "flatPath": "v1beta/projects/{projectsId}/patchJobs",
	//   "httpMethod": "GET",
	//   "id": "osconfig.projects.patchJobs.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "If provided, this field specifies the criteria that must be met by patch jobs to be included in the response. Currently, filtering is only available on the patch_deployment field.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "The maximum number of instance status to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "A pagination token returned from a previous call that indicates where this listing should continue from.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. In the form of `projects/*`",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta/{+parent}/patchJobs",
	//   "response": {
	//     "$ref": "ListPatchJobsResponse"
	//   },
	//   "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 *ProjectsPatchJobsListCall) Pages(ctx context.Context, f func(*ListPatchJobsResponse) 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 "osconfig.projects.patchJobs.instanceDetails.list":

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

// List: Get a list of instance details for a given patch job.
func (r *ProjectsPatchJobsInstanceDetailsService) List(parent string) *ProjectsPatchJobsInstanceDetailsListCall {
	c := &ProjectsPatchJobsInstanceDetailsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters results listed in the response. This field supports filtering
// results by instance zone, name, state, or `failure_reason`.
func (c *ProjectsPatchJobsInstanceDetailsListCall) Filter(filter string) *ProjectsPatchJobsInstanceDetailsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number
// of instance details records to return. Default is 100.
func (c *ProjectsPatchJobsInstanceDetailsListCall) PageSize(pageSize int64) *ProjectsPatchJobsInstanceDetailsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": A pagination token
// returned from a previous call that indicates where this listing
// should continue from.
func (c *ProjectsPatchJobsInstanceDetailsListCall) PageToken(pageToken string) *ProjectsPatchJobsInstanceDetailsListCall {
	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 *ProjectsPatchJobsInstanceDetailsListCall) Fields(s ...googleapi.Field) *ProjectsPatchJobsInstanceDetailsListCall {
	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 *ProjectsPatchJobsInstanceDetailsListCall) IfNoneMatch(entityTag string) *ProjectsPatchJobsInstanceDetailsListCall {
	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 *ProjectsPatchJobsInstanceDetailsListCall) Context(ctx context.Context) *ProjectsPatchJobsInstanceDetailsListCall {
	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 *ProjectsPatchJobsInstanceDetailsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsPatchJobsInstanceDetailsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20201002")
	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, "v1beta/{+parent}/instanceDetails")
	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 "osconfig.projects.patchJobs.instanceDetails.list" call.
// Exactly one of *ListPatchJobInstanceDetailsResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *ListPatchJobInstanceDetailsResponse.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 *ProjectsPatchJobsInstanceDetailsListCall) Do(opts ...googleapi.CallOption) (*ListPatchJobInstanceDetailsResponse, 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 := &ListPatchJobInstanceDetailsResponse{
		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": "Get a list of instance details for a given patch job.",
	//   "flatPath": "v1beta/projects/{projectsId}/patchJobs/{patchJobsId}/instanceDetails",
	//   "httpMethod": "GET",
	//   "id": "osconfig.projects.patchJobs.instanceDetails.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A filter expression that filters results listed in the response. This field supports filtering results by instance zone, name, state, or `failure_reason`.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "The maximum number of instance details records to return. Default is 100.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "A pagination token returned from a previous call that indicates where this listing should continue from.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. The parent for the instances are in the form of `projects/*/patchJobs/*`.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/patchJobs/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta/{+parent}/instanceDetails",
	//   "response": {
	//     "$ref": "ListPatchJobInstanceDetailsResponse"
	//   },
	//   "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 *ProjectsPatchJobsInstanceDetailsListCall) Pages(ctx context.Context, f func(*ListPatchJobInstanceDetailsResponse) 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 "osconfig.projects.zones.instances.lookupEffectiveGuestPolicy":

type ProjectsZonesInstancesLookupEffectiveGuestPolicyCall struct {
	s                                 *Service
	instance                          string
	lookupeffectiveguestpolicyrequest *LookupEffectiveGuestPolicyRequest
	urlParams_                        gensupport.URLParams
	ctx_                              context.Context
	header_                           http.Header
}

// LookupEffectiveGuestPolicy: Lookup the effective guest policy that
// applies to a VM instance. This lookup merges all policies that are
// assigned to the instance ancestry.
func (r *ProjectsZonesInstancesService) LookupEffectiveGuestPolicy(instance string, lookupeffectiveguestpolicyrequest *LookupEffectiveGuestPolicyRequest) *ProjectsZonesInstancesLookupEffectiveGuestPolicyCall {
	c := &ProjectsZonesInstancesLookupEffectiveGuestPolicyCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.instance = instance
	c.lookupeffectiveguestpolicyrequest = lookupeffectiveguestpolicyrequest
	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 *ProjectsZonesInstancesLookupEffectiveGuestPolicyCall) Fields(s ...googleapi.Field) *ProjectsZonesInstancesLookupEffectiveGuestPolicyCall {
	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 *ProjectsZonesInstancesLookupEffectiveGuestPolicyCall) Context(ctx context.Context) *ProjectsZonesInstancesLookupEffectiveGuestPolicyCall {
	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 *ProjectsZonesInstancesLookupEffectiveGuestPolicyCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "osconfig.projects.zones.instances.lookupEffectiveGuestPolicy" call.
// Exactly one of *EffectiveGuestPolicy or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *EffectiveGuestPolicy.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 *ProjectsZonesInstancesLookupEffectiveGuestPolicyCall) Do(opts ...googleapi.CallOption) (*EffectiveGuestPolicy, 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 := &EffectiveGuestPolicy{
		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": "Lookup the effective guest policy that applies to a VM instance. This lookup merges all policies that are assigned to the instance ancestry.",
	//   "flatPath": "v1beta/projects/{projectsId}/zones/{zonesId}/instances/{instancesId}:lookupEffectiveGuestPolicy",
	//   "httpMethod": "POST",
	//   "id": "osconfig.projects.zones.instances.lookupEffectiveGuestPolicy",
	//   "parameterOrder": [
	//     "instance"
	//   ],
	//   "parameters": {
	//     "instance": {
	//       "description": "Required. The VM instance whose policies are being looked up.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/zones/[^/]+/instances/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta/{+instance}:lookupEffectiveGuestPolicy",
	//   "request": {
	//     "$ref": "LookupEffectiveGuestPolicyRequest"
	//   },
	//   "response": {
	//     "$ref": "EffectiveGuestPolicy"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}
