// 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 Cloud OS Config API.
//
// For product documentation, see: https://cloud.google.com/
//
// 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/"

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

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

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

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

// 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#handle-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_polic
	// y_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/
// schedule-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"`

	// 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/
	// [ZONE]/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: Google 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.
//
// Instances 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"`

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

// 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`
	// thi
	// s 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)
	// Give
	// n 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:<patch_name>'
	// 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/20200518")
	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\nwith the following restrictions:\n\n* Must contain only lowercase letters, numbers, and hyphens.\n* Must start with a letter.\n* Must be between 1-63 characters.\n* Must end with a number or a letter.\n* 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:\n`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/20200518")
	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:\n`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/20200518")
	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:\n`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/20200518")
	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`\nthat 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:\n`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/20200518")
	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\nforms:\n`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\nupdated.",
	//       "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/20200518")
	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\nthe following rules apply:\n* Must contain only lowercase letters, numbers, and hyphens.\n* Must start with a letter.\n* Must be between 1-63 characters.\n* Must end with a number or a letter.\n* 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/20200518")
	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\n`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/20200518")
	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\n`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/20200518")
	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\nthat 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/20200518")
	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\ncannot 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/20200518")
	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/20200518")
	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\nongoing 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/20200518")
	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\njobs to be included in the response.\nCurrently, 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\nthat 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/20200518")
	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\nfield supports filtering results by instance zone, name, state, or\n`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\nthat 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/20200518")
	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\nlookup 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"
	//   ]
	// }

}
