// Code generated by protoc-gen-go. DO NOT EDIT.
// source: google/cloud/oslogin/v1beta/oslogin.proto

package oslogin

import (
	context "context"
	fmt "fmt"
	math "math"

	proto "github.com/golang/protobuf/proto"
	empty "github.com/golang/protobuf/ptypes/empty"
	_ "google.golang.org/genproto/googleapis/api/annotations"
	common "google.golang.org/genproto/googleapis/cloud/oslogin/common"
	field_mask "google.golang.org/genproto/protobuf/field_mask"
	grpc "google.golang.org/grpc"
	codes "google.golang.org/grpc/codes"
	status "google.golang.org/grpc/status"
)

// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf

// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package

// The user profile information used for logging in to a virtual machine on
// Google Compute Engine.
type LoginProfile struct {
	// Required. A unique user ID.
	Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
	// The list of POSIX accounts associated with the user.
	PosixAccounts []*common.PosixAccount `protobuf:"bytes,2,rep,name=posix_accounts,json=posixAccounts,proto3" json:"posix_accounts,omitempty"`
	// A map from SSH public key fingerprint to the associated key object.
	SshPublicKeys        map[string]*common.SshPublicKey `protobuf:"bytes,3,rep,name=ssh_public_keys,json=sshPublicKeys,proto3" json:"ssh_public_keys,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
	XXX_NoUnkeyedLiteral struct{}                        `json:"-"`
	XXX_unrecognized     []byte                          `json:"-"`
	XXX_sizecache        int32                           `json:"-"`
}

func (m *LoginProfile) Reset()         { *m = LoginProfile{} }
func (m *LoginProfile) String() string { return proto.CompactTextString(m) }
func (*LoginProfile) ProtoMessage()    {}
func (*LoginProfile) Descriptor() ([]byte, []int) {
	return fileDescriptor_c51261020b887e3b, []int{0}
}

func (m *LoginProfile) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_LoginProfile.Unmarshal(m, b)
}
func (m *LoginProfile) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_LoginProfile.Marshal(b, m, deterministic)
}
func (m *LoginProfile) XXX_Merge(src proto.Message) {
	xxx_messageInfo_LoginProfile.Merge(m, src)
}
func (m *LoginProfile) XXX_Size() int {
	return xxx_messageInfo_LoginProfile.Size(m)
}
func (m *LoginProfile) XXX_DiscardUnknown() {
	xxx_messageInfo_LoginProfile.DiscardUnknown(m)
}

var xxx_messageInfo_LoginProfile proto.InternalMessageInfo

func (m *LoginProfile) GetName() string {
	if m != nil {
		return m.Name
	}
	return ""
}

func (m *LoginProfile) GetPosixAccounts() []*common.PosixAccount {
	if m != nil {
		return m.PosixAccounts
	}
	return nil
}

func (m *LoginProfile) GetSshPublicKeys() map[string]*common.SshPublicKey {
	if m != nil {
		return m.SshPublicKeys
	}
	return nil
}

// A request message for deleting a POSIX account entry.
type DeletePosixAccountRequest struct {
	// Required. A reference to the POSIX account to update. POSIX accounts are identified
	// by the project ID they are associated with. A reference to the POSIX
	// account is in format `users/{user}/projects/{project}`.
	Name                 string   `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func (m *DeletePosixAccountRequest) Reset()         { *m = DeletePosixAccountRequest{} }
func (m *DeletePosixAccountRequest) String() string { return proto.CompactTextString(m) }
func (*DeletePosixAccountRequest) ProtoMessage()    {}
func (*DeletePosixAccountRequest) Descriptor() ([]byte, []int) {
	return fileDescriptor_c51261020b887e3b, []int{1}
}

func (m *DeletePosixAccountRequest) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_DeletePosixAccountRequest.Unmarshal(m, b)
}
func (m *DeletePosixAccountRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_DeletePosixAccountRequest.Marshal(b, m, deterministic)
}
func (m *DeletePosixAccountRequest) XXX_Merge(src proto.Message) {
	xxx_messageInfo_DeletePosixAccountRequest.Merge(m, src)
}
func (m *DeletePosixAccountRequest) XXX_Size() int {
	return xxx_messageInfo_DeletePosixAccountRequest.Size(m)
}
func (m *DeletePosixAccountRequest) XXX_DiscardUnknown() {
	xxx_messageInfo_DeletePosixAccountRequest.DiscardUnknown(m)
}

var xxx_messageInfo_DeletePosixAccountRequest proto.InternalMessageInfo

func (m *DeletePosixAccountRequest) GetName() string {
	if m != nil {
		return m.Name
	}
	return ""
}

// A request message for deleting an SSH public key.
type DeleteSshPublicKeyRequest struct {
	// Required. The fingerprint of the public key to update. Public keys are identified by
	// their SHA-256 fingerprint. The fingerprint of the public key is in format
	// `users/{user}/sshPublicKeys/{fingerprint}`.
	Name                 string   `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func (m *DeleteSshPublicKeyRequest) Reset()         { *m = DeleteSshPublicKeyRequest{} }
func (m *DeleteSshPublicKeyRequest) String() string { return proto.CompactTextString(m) }
func (*DeleteSshPublicKeyRequest) ProtoMessage()    {}
func (*DeleteSshPublicKeyRequest) Descriptor() ([]byte, []int) {
	return fileDescriptor_c51261020b887e3b, []int{2}
}

func (m *DeleteSshPublicKeyRequest) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_DeleteSshPublicKeyRequest.Unmarshal(m, b)
}
func (m *DeleteSshPublicKeyRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_DeleteSshPublicKeyRequest.Marshal(b, m, deterministic)
}
func (m *DeleteSshPublicKeyRequest) XXX_Merge(src proto.Message) {
	xxx_messageInfo_DeleteSshPublicKeyRequest.Merge(m, src)
}
func (m *DeleteSshPublicKeyRequest) XXX_Size() int {
	return xxx_messageInfo_DeleteSshPublicKeyRequest.Size(m)
}
func (m *DeleteSshPublicKeyRequest) XXX_DiscardUnknown() {
	xxx_messageInfo_DeleteSshPublicKeyRequest.DiscardUnknown(m)
}

var xxx_messageInfo_DeleteSshPublicKeyRequest proto.InternalMessageInfo

func (m *DeleteSshPublicKeyRequest) GetName() string {
	if m != nil {
		return m.Name
	}
	return ""
}

// A request message for retrieving the login profile information for a user.
type GetLoginProfileRequest struct {
	// Required. The unique ID for the user in format `users/{user}`.
	Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
	// The project ID of the Google Cloud Platform project.
	ProjectId string `protobuf:"bytes,2,opt,name=project_id,json=projectId,proto3" json:"project_id,omitempty"`
	// A system ID for filtering the results of the request.
	SystemId             string   `protobuf:"bytes,3,opt,name=system_id,json=systemId,proto3" json:"system_id,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func (m *GetLoginProfileRequest) Reset()         { *m = GetLoginProfileRequest{} }
func (m *GetLoginProfileRequest) String() string { return proto.CompactTextString(m) }
func (*GetLoginProfileRequest) ProtoMessage()    {}
func (*GetLoginProfileRequest) Descriptor() ([]byte, []int) {
	return fileDescriptor_c51261020b887e3b, []int{3}
}

func (m *GetLoginProfileRequest) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_GetLoginProfileRequest.Unmarshal(m, b)
}
func (m *GetLoginProfileRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_GetLoginProfileRequest.Marshal(b, m, deterministic)
}
func (m *GetLoginProfileRequest) XXX_Merge(src proto.Message) {
	xxx_messageInfo_GetLoginProfileRequest.Merge(m, src)
}
func (m *GetLoginProfileRequest) XXX_Size() int {
	return xxx_messageInfo_GetLoginProfileRequest.Size(m)
}
func (m *GetLoginProfileRequest) XXX_DiscardUnknown() {
	xxx_messageInfo_GetLoginProfileRequest.DiscardUnknown(m)
}

var xxx_messageInfo_GetLoginProfileRequest proto.InternalMessageInfo

func (m *GetLoginProfileRequest) GetName() string {
	if m != nil {
		return m.Name
	}
	return ""
}

func (m *GetLoginProfileRequest) GetProjectId() string {
	if m != nil {
		return m.ProjectId
	}
	return ""
}

func (m *GetLoginProfileRequest) GetSystemId() string {
	if m != nil {
		return m.SystemId
	}
	return ""
}

// A request message for retrieving an SSH public key.
type GetSshPublicKeyRequest struct {
	// Required. The fingerprint of the public key to retrieve. Public keys are identified
	// by their SHA-256 fingerprint. The fingerprint of the public key is in
	// format `users/{user}/sshPublicKeys/{fingerprint}`.
	Name                 string   `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func (m *GetSshPublicKeyRequest) Reset()         { *m = GetSshPublicKeyRequest{} }
func (m *GetSshPublicKeyRequest) String() string { return proto.CompactTextString(m) }
func (*GetSshPublicKeyRequest) ProtoMessage()    {}
func (*GetSshPublicKeyRequest) Descriptor() ([]byte, []int) {
	return fileDescriptor_c51261020b887e3b, []int{4}
}

func (m *GetSshPublicKeyRequest) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_GetSshPublicKeyRequest.Unmarshal(m, b)
}
func (m *GetSshPublicKeyRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_GetSshPublicKeyRequest.Marshal(b, m, deterministic)
}
func (m *GetSshPublicKeyRequest) XXX_Merge(src proto.Message) {
	xxx_messageInfo_GetSshPublicKeyRequest.Merge(m, src)
}
func (m *GetSshPublicKeyRequest) XXX_Size() int {
	return xxx_messageInfo_GetSshPublicKeyRequest.Size(m)
}
func (m *GetSshPublicKeyRequest) XXX_DiscardUnknown() {
	xxx_messageInfo_GetSshPublicKeyRequest.DiscardUnknown(m)
}

var xxx_messageInfo_GetSshPublicKeyRequest proto.InternalMessageInfo

func (m *GetSshPublicKeyRequest) GetName() string {
	if m != nil {
		return m.Name
	}
	return ""
}

// A request message for importing an SSH public key.
type ImportSshPublicKeyRequest struct {
	// The unique ID for the user in format `users/{user}`.
	Parent string `protobuf:"bytes,1,opt,name=parent,proto3" json:"parent,omitempty"`
	// Required. The SSH public key and expiration time.
	SshPublicKey *common.SshPublicKey `protobuf:"bytes,2,opt,name=ssh_public_key,json=sshPublicKey,proto3" json:"ssh_public_key,omitempty"`
	// The project ID of the Google Cloud Platform project.
	ProjectId            string   `protobuf:"bytes,3,opt,name=project_id,json=projectId,proto3" json:"project_id,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func (m *ImportSshPublicKeyRequest) Reset()         { *m = ImportSshPublicKeyRequest{} }
func (m *ImportSshPublicKeyRequest) String() string { return proto.CompactTextString(m) }
func (*ImportSshPublicKeyRequest) ProtoMessage()    {}
func (*ImportSshPublicKeyRequest) Descriptor() ([]byte, []int) {
	return fileDescriptor_c51261020b887e3b, []int{5}
}

func (m *ImportSshPublicKeyRequest) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_ImportSshPublicKeyRequest.Unmarshal(m, b)
}
func (m *ImportSshPublicKeyRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_ImportSshPublicKeyRequest.Marshal(b, m, deterministic)
}
func (m *ImportSshPublicKeyRequest) XXX_Merge(src proto.Message) {
	xxx_messageInfo_ImportSshPublicKeyRequest.Merge(m, src)
}
func (m *ImportSshPublicKeyRequest) XXX_Size() int {
	return xxx_messageInfo_ImportSshPublicKeyRequest.Size(m)
}
func (m *ImportSshPublicKeyRequest) XXX_DiscardUnknown() {
	xxx_messageInfo_ImportSshPublicKeyRequest.DiscardUnknown(m)
}

var xxx_messageInfo_ImportSshPublicKeyRequest proto.InternalMessageInfo

func (m *ImportSshPublicKeyRequest) GetParent() string {
	if m != nil {
		return m.Parent
	}
	return ""
}

func (m *ImportSshPublicKeyRequest) GetSshPublicKey() *common.SshPublicKey {
	if m != nil {
		return m.SshPublicKey
	}
	return nil
}

func (m *ImportSshPublicKeyRequest) GetProjectId() string {
	if m != nil {
		return m.ProjectId
	}
	return ""
}

// A response message for importing an SSH public key.
type ImportSshPublicKeyResponse struct {
	// The login profile information for the user.
	LoginProfile         *LoginProfile `protobuf:"bytes,1,opt,name=login_profile,json=loginProfile,proto3" json:"login_profile,omitempty"`
	XXX_NoUnkeyedLiteral struct{}      `json:"-"`
	XXX_unrecognized     []byte        `json:"-"`
	XXX_sizecache        int32         `json:"-"`
}

func (m *ImportSshPublicKeyResponse) Reset()         { *m = ImportSshPublicKeyResponse{} }
func (m *ImportSshPublicKeyResponse) String() string { return proto.CompactTextString(m) }
func (*ImportSshPublicKeyResponse) ProtoMessage()    {}
func (*ImportSshPublicKeyResponse) Descriptor() ([]byte, []int) {
	return fileDescriptor_c51261020b887e3b, []int{6}
}

func (m *ImportSshPublicKeyResponse) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_ImportSshPublicKeyResponse.Unmarshal(m, b)
}
func (m *ImportSshPublicKeyResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_ImportSshPublicKeyResponse.Marshal(b, m, deterministic)
}
func (m *ImportSshPublicKeyResponse) XXX_Merge(src proto.Message) {
	xxx_messageInfo_ImportSshPublicKeyResponse.Merge(m, src)
}
func (m *ImportSshPublicKeyResponse) XXX_Size() int {
	return xxx_messageInfo_ImportSshPublicKeyResponse.Size(m)
}
func (m *ImportSshPublicKeyResponse) XXX_DiscardUnknown() {
	xxx_messageInfo_ImportSshPublicKeyResponse.DiscardUnknown(m)
}

var xxx_messageInfo_ImportSshPublicKeyResponse proto.InternalMessageInfo

func (m *ImportSshPublicKeyResponse) GetLoginProfile() *LoginProfile {
	if m != nil {
		return m.LoginProfile
	}
	return nil
}

// A request message for updating an SSH public key.
type UpdateSshPublicKeyRequest struct {
	// Required. The fingerprint of the public key to update. Public keys are identified by
	// their SHA-256 fingerprint. The fingerprint of the public key is in format
	// `users/{user}/sshPublicKeys/{fingerprint}`.
	Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
	// Required. The SSH public key and expiration time.
	SshPublicKey *common.SshPublicKey `protobuf:"bytes,2,opt,name=ssh_public_key,json=sshPublicKey,proto3" json:"ssh_public_key,omitempty"`
	// Mask to control which fields get updated. Updates all if not present.
	UpdateMask           *field_mask.FieldMask `protobuf:"bytes,3,opt,name=update_mask,json=updateMask,proto3" json:"update_mask,omitempty"`
	XXX_NoUnkeyedLiteral struct{}              `json:"-"`
	XXX_unrecognized     []byte                `json:"-"`
	XXX_sizecache        int32                 `json:"-"`
}

func (m *UpdateSshPublicKeyRequest) Reset()         { *m = UpdateSshPublicKeyRequest{} }
func (m *UpdateSshPublicKeyRequest) String() string { return proto.CompactTextString(m) }
func (*UpdateSshPublicKeyRequest) ProtoMessage()    {}
func (*UpdateSshPublicKeyRequest) Descriptor() ([]byte, []int) {
	return fileDescriptor_c51261020b887e3b, []int{7}
}

func (m *UpdateSshPublicKeyRequest) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_UpdateSshPublicKeyRequest.Unmarshal(m, b)
}
func (m *UpdateSshPublicKeyRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_UpdateSshPublicKeyRequest.Marshal(b, m, deterministic)
}
func (m *UpdateSshPublicKeyRequest) XXX_Merge(src proto.Message) {
	xxx_messageInfo_UpdateSshPublicKeyRequest.Merge(m, src)
}
func (m *UpdateSshPublicKeyRequest) XXX_Size() int {
	return xxx_messageInfo_UpdateSshPublicKeyRequest.Size(m)
}
func (m *UpdateSshPublicKeyRequest) XXX_DiscardUnknown() {
	xxx_messageInfo_UpdateSshPublicKeyRequest.DiscardUnknown(m)
}

var xxx_messageInfo_UpdateSshPublicKeyRequest proto.InternalMessageInfo

func (m *UpdateSshPublicKeyRequest) GetName() string {
	if m != nil {
		return m.Name
	}
	return ""
}

func (m *UpdateSshPublicKeyRequest) GetSshPublicKey() *common.SshPublicKey {
	if m != nil {
		return m.SshPublicKey
	}
	return nil
}

func (m *UpdateSshPublicKeyRequest) GetUpdateMask() *field_mask.FieldMask {
	if m != nil {
		return m.UpdateMask
	}
	return nil
}

func init() {
	proto.RegisterType((*LoginProfile)(nil), "google.cloud.oslogin.v1beta.LoginProfile")
	proto.RegisterMapType((map[string]*common.SshPublicKey)(nil), "google.cloud.oslogin.v1beta.LoginProfile.SshPublicKeysEntry")
	proto.RegisterType((*DeletePosixAccountRequest)(nil), "google.cloud.oslogin.v1beta.DeletePosixAccountRequest")
	proto.RegisterType((*DeleteSshPublicKeyRequest)(nil), "google.cloud.oslogin.v1beta.DeleteSshPublicKeyRequest")
	proto.RegisterType((*GetLoginProfileRequest)(nil), "google.cloud.oslogin.v1beta.GetLoginProfileRequest")
	proto.RegisterType((*GetSshPublicKeyRequest)(nil), "google.cloud.oslogin.v1beta.GetSshPublicKeyRequest")
	proto.RegisterType((*ImportSshPublicKeyRequest)(nil), "google.cloud.oslogin.v1beta.ImportSshPublicKeyRequest")
	proto.RegisterType((*ImportSshPublicKeyResponse)(nil), "google.cloud.oslogin.v1beta.ImportSshPublicKeyResponse")
	proto.RegisterType((*UpdateSshPublicKeyRequest)(nil), "google.cloud.oslogin.v1beta.UpdateSshPublicKeyRequest")
}

func init() {
	proto.RegisterFile("google/cloud/oslogin/v1beta/oslogin.proto", fileDescriptor_c51261020b887e3b)
}

var fileDescriptor_c51261020b887e3b = []byte{
	// 988 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x57, 0xcd, 0x6f, 0xdc, 0x44,
	0x14, 0x97, 0xbd, 0x50, 0x91, 0xc9, 0x47, 0xd1, 0x20, 0xd2, 0xc4, 0xa1, 0xca, 0xe2, 0x28, 0x68,
	0x9b, 0xa6, 0x36, 0xdd, 0x0a, 0x5a, 0xa5, 0x54, 0xc5, 0x0b, 0xa5, 0x8a, 0xf8, 0x5a, 0x6d, 0x69,
	0x25, 0x50, 0xa4, 0xd5, 0xac, 0x77, 0xb2, 0x6b, 0xd6, 0xf6, 0x0c, 0x9e, 0xf1, 0x86, 0x15, 0x2a,
	0x07, 0x24, 0x8e, 0x9c, 0x90, 0xb8, 0x70, 0x46, 0x42, 0xdc, 0xf8, 0x0f, 0x38, 0x57, 0x9c, 0xca,
	0x2d, 0x12, 0x52, 0x0f, 0xdc, 0x7b, 0xe1, 0x94, 0x13, 0xf2, 0xcc, 0x38, 0xb1, 0xbd, 0xde, 0xec,
	0x06, 0x29, 0xa7, 0x78, 0xe6, 0xbd, 0xf7, 0x7b, 0xbf, 0xf7, 0x31, 0xbf, 0x24, 0xe0, 0x4a, 0x8f,
	0x90, 0x9e, 0x8f, 0x6d, 0xd7, 0x27, 0x71, 0xd7, 0x26, 0xcc, 0x27, 0x3d, 0x2f, 0xb4, 0x87, 0xd7,
	0x3b, 0x98, 0xa3, 0xf4, 0x68, 0xd1, 0x88, 0x70, 0x02, 0xd7, 0xa4, 0xab, 0x25, 0x5c, 0xad, 0xd4,
	0x26, 0x5d, 0x8d, 0xd7, 0x14, 0x0e, 0xa2, 0x9e, 0x8d, 0xc2, 0x90, 0x70, 0xc4, 0x3d, 0x12, 0x32,
	0x19, 0x6a, 0x5c, 0xca, 0x58, 0x5d, 0xdf, 0xc3, 0x21, 0x57, 0x86, 0xf5, 0x8c, 0x61, 0xdf, 0xc3,
	0x7e, 0xb7, 0xdd, 0xc1, 0x7d, 0x34, 0xf4, 0x48, 0xa4, 0x1c, 0x56, 0x33, 0x0e, 0x11, 0x66, 0x24,
	0x8e, 0x5c, 0xac, 0x4c, 0xb5, 0x52, 0xea, 0x2e, 0x09, 0x02, 0x92, 0xfe, 0x50, 0x9e, 0x8a, 0xb9,
	0x2d, 0x4e, 0x9d, 0x78, 0xdf, 0xc6, 0x01, 0xe5, 0x23, 0x65, 0xac, 0x16, 0x8d, 0x92, 0x47, 0x80,
	0xd8, 0x40, 0x7a, 0x98, 0x7f, 0xea, 0x60, 0xe1, 0xa3, 0x04, 0xbc, 0x19, 0x91, 0x7d, 0xcf, 0xc7,
	0xf0, 0x12, 0x78, 0x21, 0x44, 0x01, 0x5e, 0xd1, 0xaa, 0x5a, 0x6d, 0xae, 0x51, 0x79, 0xe6, 0xe8,
	0x2d, 0x71, 0x01, 0x9b, 0x60, 0x89, 0x12, 0xe6, 0x7d, 0xdd, 0x46, 0xae, 0x4b, 0xe2, 0x90, 0xb3,
	0x15, 0xbd, 0x5a, 0xa9, 0xcd, 0xd7, 0xaf, 0x58, 0xa5, 0xbd, 0x53, 0x24, 0x9b, 0x49, 0x88, 0x23,
	0x23, 0x5a, 0x8b, 0x34, 0x73, 0x62, 0xb0, 0x0b, 0x2e, 0x32, 0xd6, 0x6f, 0xd3, 0xb8, 0xe3, 0x7b,
	0x6e, 0x7b, 0x80, 0x47, 0x6c, 0xa5, 0x22, 0x20, 0xdf, 0xb1, 0x4e, 0x19, 0x87, 0x95, 0xa5, 0x6b,
	0x3d, 0x60, 0xfd, 0xa6, 0x88, 0xff, 0x10, 0x8f, 0xd8, 0xbd, 0x90, 0x47, 0xa3, 0xd6, 0x22, 0xcb,
	0xde, 0x19, 0x03, 0x00, 0xc7, 0x9d, 0xe0, 0xcb, 0xa0, 0x32, 0xc0, 0x23, 0x59, 0x65, 0x2b, 0xf9,
	0x84, 0x77, 0xc1, 0x8b, 0x43, 0xe4, 0xc7, 0x78, 0x45, 0xaf, 0x6a, 0x53, 0xcb, 0xca, 0x22, 0xb6,
	0x64, 0xdc, 0x8e, 0x7e, 0x4b, 0x33, 0xf7, 0xc0, 0xea, 0xfb, 0xd8, 0xc7, 0x1c, 0xe7, 0xea, 0xc6,
	0x5f, 0xc5, 0x98, 0x71, 0x78, 0x37, 0xd7, 0xda, 0xab, 0xcf, 0x1c, 0xfd, 0xc8, 0xd9, 0x04, 0x1b,
	0x29, 0xb4, 0xcc, 0x87, 0xa8, 0xc7, 0x92, 0x2c, 0x76, 0x0e, 0x41, 0x04, 0x9e, 0xa0, 0xe7, 0xd2,
	0xff, 0x2f, 0xf4, 0x1c, 0x82, 0x44, 0xff, 0x41, 0x03, 0xcb, 0xf7, 0x31, 0xcf, 0xb6, 0x37, 0xc5,
	0xbe, 0x99, 0xc3, 0xde, 0x10, 0xd8, 0x97, 0xc1, 0xda, 0x04, 0xec, 0x87, 0x0c, 0x47, 0x6a, 0x69,
	0x2e, 0x03, 0x40, 0x23, 0xf2, 0x25, 0x76, 0x79, 0xdb, 0xeb, 0x8a, 0xce, 0xce, 0xb5, 0xe6, 0xd4,
	0xcd, 0x6e, 0x17, 0xae, 0x81, 0x39, 0x36, 0x62, 0x1c, 0x07, 0x89, 0xb5, 0x22, 0xac, 0x2f, 0xc9,
	0x8b, 0xdd, 0xae, 0xf9, 0xb9, 0xa0, 0x73, 0x2e, 0xa5, 0x3e, 0xd5, 0xc0, 0xea, 0x6e, 0x40, 0x49,
	0x54, 0x0a, 0xff, 0x2e, 0xb8, 0x40, 0x51, 0x84, 0x43, 0xae, 0x12, 0xd4, 0x8e, 0x9c, 0x4d, 0x38,
	0x13, 0xba, 0x8a, 0x83, 0x9f, 0x81, 0xa5, 0xfc, 0x66, 0x9f, 0x79, 0xa9, 0xe4, 0xcb, 0x5b, 0xc8,
	0xae, 0x72, 0xa1, 0x99, 0x95, 0x42, 0x33, 0x4d, 0x1f, 0x18, 0x65, 0x35, 0x31, 0x4a, 0x42, 0x86,
	0xe1, 0x27, 0x60, 0x51, 0x24, 0x6b, 0x53, 0x39, 0x5a, 0x51, 0xdb, 0x44, 0x46, 0x25, 0x4f, 0xad,
	0xb5, 0xe0, 0x67, 0x4e, 0xe6, 0x73, 0x0d, 0xac, 0x3e, 0xa4, 0x5d, 0x74, 0x3e, 0xcb, 0x78, 0x4e,
	0x1d, 0xbc, 0x0d, 0xe6, 0x63, 0xc1, 0x59, 0x48, 0xa0, 0x68, 0xe1, 0x7c, 0xdd, 0x48, 0x21, 0x53,
	0x95, 0xb4, 0x3e, 0x48, 0x54, 0xf2, 0x63, 0xc4, 0x06, 0x2d, 0x20, 0xdd, 0x93, 0xef, 0xfa, 0xbf,
	0x00, 0x2c, 0x7d, 0xca, 0x44, 0x4b, 0x1e, 0xe0, 0x68, 0xe8, 0xb9, 0x18, 0xfe, 0xa4, 0x01, 0x38,
	0xfe, 0xde, 0xe1, 0xdb, 0xa7, 0x36, 0x75, 0xa2, 0x40, 0x18, 0xcb, 0x63, 0x4c, 0xee, 0x25, 0x62,
	0x6e, 0xbe, 0x79, 0xe8, 0x88, 0xae, 0x7c, 0xf7, 0xd7, 0x3f, 0x3f, 0xea, 0x1b, 0x5b, 0xaf, 0xa7,
	0xbf, 0xc3, 0xbe, 0x49, 0x2e, 0xef, 0xc4, 0x0c, 0x47, 0xcc, 0xde, 0xb2, 0xd5, 0x26, 0x30, 0x7b,
	0xeb, 0x31, 0xfc, 0xf9, 0x98, 0x58, 0xb6, 0x25, 0x33, 0x11, 0x2b, 0x19, 0xe7, 0x44, 0x62, 0x6f,
	0x65, 0x89, 0xd5, 0xb6, 0xde, 0x28, 0x27, 0x96, 0xd3, 0xe3, 0x84, 0xdd, 0x2f, 0x1a, 0xb8, 0x58,
	0x50, 0x1a, 0x78, 0xe3, 0x54, 0x6a, 0xe5, 0xba, 0x64, 0xcc, 0xbe, 0xbd, 0x66, 0x3d, 0x4b, 0x75,
	0x13, 0x6e, 0x94, 0x52, 0x7d, 0x6c, 0x67, 0x77, 0x1c, 0xfe, 0x2a, 0x79, 0xe6, 0x5a, 0x38, 0x95,
	0x67, 0x59, 0xff, 0x66, 0xdf, 0xda, 0x42, 0x4b, 0xe1, 0xac, 0x2d, 0xfd, 0x5e, 0x07, 0x70, 0xfc,
	0xf5, 0x4f, 0x19, 0xf8, 0x44, 0x09, 0x34, 0x6e, 0x9e, 0x39, 0x4e, 0xca, 0x8c, 0xf9, 0xed, 0xa1,
	0xf3, 0xaa, 0x14, 0xc1, 0xed, 0xfc, 0xfb, 0x3d, 0x74, 0xaa, 0xa5, 0xf7, 0xdb, 0x27, 0x92, 0x26,
	0x4a, 0xbe, 0x63, 0x5e, 0x3d, 0x2e, 0x59, 0x06, 0x1c, 0x0f, 0x67, 0xc7, 0x1b, 0xcb, 0xbb, 0x53,
	0x50, 0x09, 0xf8, 0x5c, 0x03, 0x70, 0x5c, 0x96, 0xa6, 0xf4, 0x61, 0xa2, 0x8e, 0x9d, 0x65, 0x70,
	0xc3, 0x43, 0xe7, 0x95, 0x64, 0x46, 0x63, 0x75, 0xaf, 0x97, 0xdc, 0x6e, 0x67, 0x64, 0x48, 0x94,
	0x7d, 0xab, 0x3e, 0xe3, 0xa4, 0x8b, 0x15, 0x1b, 0x7f, 0x6b, 0x4f, 0x9c, 0xe5, 0x72, 0x61, 0x7d,
	0xea, 0xfc, 0xa1, 0xf5, 0x39, 0xa7, 0x6c, 0xc7, 0xb6, 0x0f, 0x0e, 0x0e, 0x8a, 0xb2, 0x8b, 0x62,
	0xde, 0x97, 0x7f, 0x61, 0x5e, 0xa3, 0x3e, 0xe2, 0xfb, 0x24, 0x0a, 0xb6, 0xcf, 0xe6, 0x6e, 0x45,
	0x18, 0x75, 0xaf, 0x91, 0xd0, 0x1f, 0x4d, 0x0f, 0x24, 0x01, 0x8d, 0x39, 0x9e, 0xd5, 0x4f, 0x20,
	0x27, 0xc0, 0x8d, 0xdf, 0x35, 0xb0, 0xee, 0x92, 0xe0, 0xb4, 0x01, 0x36, 0x16, 0x94, 0x2e, 0x37,
	0x13, 0x79, 0x6a, 0x6a, 0x5f, 0x34, 0x94, 0x73, 0x8f, 0xf8, 0x28, 0xec, 0x59, 0x24, 0xea, 0xd9,
	0x3d, 0x1c, 0x0a, 0xf1, 0xb2, 0x4f, 0x92, 0x96, 0xfe, 0x63, 0x70, 0x5b, 0x1d, 0x7f, 0xd3, 0xd7,
	0xee, 0x4b, 0x90, 0xf7, 0x44, 0x46, 0x95, 0xc1, 0x7a, 0x74, 0xbd, 0x81, 0x39, 0x7a, 0x92, 0x5a,
	0xf7, 0x84, 0x75, 0x4f, 0x59, 0xf7, 0x1e, 0x09, 0x8c, 0xce, 0x05, 0x91, 0xea, 0xc6, 0x7f, 0x01,
	0x00, 0x00, 0xff, 0xff, 0xc7, 0xd3, 0xe2, 0x5e, 0x82, 0x0c, 0x00, 0x00,
}

// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConnInterface

// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion6

// OsLoginServiceClient is the client API for OsLoginService service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type OsLoginServiceClient interface {
	// Deletes a POSIX account.
	DeletePosixAccount(ctx context.Context, in *DeletePosixAccountRequest, opts ...grpc.CallOption) (*empty.Empty, error)
	// Deletes an SSH public key.
	DeleteSshPublicKey(ctx context.Context, in *DeleteSshPublicKeyRequest, opts ...grpc.CallOption) (*empty.Empty, error)
	// Retrieves the profile information used for logging in to a virtual machine
	// on Google Compute Engine.
	GetLoginProfile(ctx context.Context, in *GetLoginProfileRequest, opts ...grpc.CallOption) (*LoginProfile, error)
	// Retrieves an SSH public key.
	GetSshPublicKey(ctx context.Context, in *GetSshPublicKeyRequest, opts ...grpc.CallOption) (*common.SshPublicKey, error)
	// Adds an SSH public key and returns the profile information. Default POSIX
	// account information is set when no username and UID exist as part of the
	// login profile.
	ImportSshPublicKey(ctx context.Context, in *ImportSshPublicKeyRequest, opts ...grpc.CallOption) (*ImportSshPublicKeyResponse, error)
	// Updates an SSH public key and returns the profile information. This method
	// supports patch semantics.
	UpdateSshPublicKey(ctx context.Context, in *UpdateSshPublicKeyRequest, opts ...grpc.CallOption) (*common.SshPublicKey, error)
}

type osLoginServiceClient struct {
	cc grpc.ClientConnInterface
}

func NewOsLoginServiceClient(cc grpc.ClientConnInterface) OsLoginServiceClient {
	return &osLoginServiceClient{cc}
}

func (c *osLoginServiceClient) DeletePosixAccount(ctx context.Context, in *DeletePosixAccountRequest, opts ...grpc.CallOption) (*empty.Empty, error) {
	out := new(empty.Empty)
	err := c.cc.Invoke(ctx, "/google.cloud.oslogin.v1beta.OsLoginService/DeletePosixAccount", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *osLoginServiceClient) DeleteSshPublicKey(ctx context.Context, in *DeleteSshPublicKeyRequest, opts ...grpc.CallOption) (*empty.Empty, error) {
	out := new(empty.Empty)
	err := c.cc.Invoke(ctx, "/google.cloud.oslogin.v1beta.OsLoginService/DeleteSshPublicKey", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *osLoginServiceClient) GetLoginProfile(ctx context.Context, in *GetLoginProfileRequest, opts ...grpc.CallOption) (*LoginProfile, error) {
	out := new(LoginProfile)
	err := c.cc.Invoke(ctx, "/google.cloud.oslogin.v1beta.OsLoginService/GetLoginProfile", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *osLoginServiceClient) GetSshPublicKey(ctx context.Context, in *GetSshPublicKeyRequest, opts ...grpc.CallOption) (*common.SshPublicKey, error) {
	out := new(common.SshPublicKey)
	err := c.cc.Invoke(ctx, "/google.cloud.oslogin.v1beta.OsLoginService/GetSshPublicKey", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *osLoginServiceClient) ImportSshPublicKey(ctx context.Context, in *ImportSshPublicKeyRequest, opts ...grpc.CallOption) (*ImportSshPublicKeyResponse, error) {
	out := new(ImportSshPublicKeyResponse)
	err := c.cc.Invoke(ctx, "/google.cloud.oslogin.v1beta.OsLoginService/ImportSshPublicKey", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *osLoginServiceClient) UpdateSshPublicKey(ctx context.Context, in *UpdateSshPublicKeyRequest, opts ...grpc.CallOption) (*common.SshPublicKey, error) {
	out := new(common.SshPublicKey)
	err := c.cc.Invoke(ctx, "/google.cloud.oslogin.v1beta.OsLoginService/UpdateSshPublicKey", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

// OsLoginServiceServer is the server API for OsLoginService service.
type OsLoginServiceServer interface {
	// Deletes a POSIX account.
	DeletePosixAccount(context.Context, *DeletePosixAccountRequest) (*empty.Empty, error)
	// Deletes an SSH public key.
	DeleteSshPublicKey(context.Context, *DeleteSshPublicKeyRequest) (*empty.Empty, error)
	// Retrieves the profile information used for logging in to a virtual machine
	// on Google Compute Engine.
	GetLoginProfile(context.Context, *GetLoginProfileRequest) (*LoginProfile, error)
	// Retrieves an SSH public key.
	GetSshPublicKey(context.Context, *GetSshPublicKeyRequest) (*common.SshPublicKey, error)
	// Adds an SSH public key and returns the profile information. Default POSIX
	// account information is set when no username and UID exist as part of the
	// login profile.
	ImportSshPublicKey(context.Context, *ImportSshPublicKeyRequest) (*ImportSshPublicKeyResponse, error)
	// Updates an SSH public key and returns the profile information. This method
	// supports patch semantics.
	UpdateSshPublicKey(context.Context, *UpdateSshPublicKeyRequest) (*common.SshPublicKey, error)
}

// UnimplementedOsLoginServiceServer can be embedded to have forward compatible implementations.
type UnimplementedOsLoginServiceServer struct {
}

func (*UnimplementedOsLoginServiceServer) DeletePosixAccount(ctx context.Context, req *DeletePosixAccountRequest) (*empty.Empty, error) {
	return nil, status.Errorf(codes.Unimplemented, "method DeletePosixAccount not implemented")
}
func (*UnimplementedOsLoginServiceServer) DeleteSshPublicKey(ctx context.Context, req *DeleteSshPublicKeyRequest) (*empty.Empty, error) {
	return nil, status.Errorf(codes.Unimplemented, "method DeleteSshPublicKey not implemented")
}
func (*UnimplementedOsLoginServiceServer) GetLoginProfile(ctx context.Context, req *GetLoginProfileRequest) (*LoginProfile, error) {
	return nil, status.Errorf(codes.Unimplemented, "method GetLoginProfile not implemented")
}
func (*UnimplementedOsLoginServiceServer) GetSshPublicKey(ctx context.Context, req *GetSshPublicKeyRequest) (*common.SshPublicKey, error) {
	return nil, status.Errorf(codes.Unimplemented, "method GetSshPublicKey not implemented")
}
func (*UnimplementedOsLoginServiceServer) ImportSshPublicKey(ctx context.Context, req *ImportSshPublicKeyRequest) (*ImportSshPublicKeyResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method ImportSshPublicKey not implemented")
}
func (*UnimplementedOsLoginServiceServer) UpdateSshPublicKey(ctx context.Context, req *UpdateSshPublicKeyRequest) (*common.SshPublicKey, error) {
	return nil, status.Errorf(codes.Unimplemented, "method UpdateSshPublicKey not implemented")
}

func RegisterOsLoginServiceServer(s *grpc.Server, srv OsLoginServiceServer) {
	s.RegisterService(&_OsLoginService_serviceDesc, srv)
}

func _OsLoginService_DeletePosixAccount_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(DeletePosixAccountRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(OsLoginServiceServer).DeletePosixAccount(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/google.cloud.oslogin.v1beta.OsLoginService/DeletePosixAccount",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(OsLoginServiceServer).DeletePosixAccount(ctx, req.(*DeletePosixAccountRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _OsLoginService_DeleteSshPublicKey_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(DeleteSshPublicKeyRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(OsLoginServiceServer).DeleteSshPublicKey(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/google.cloud.oslogin.v1beta.OsLoginService/DeleteSshPublicKey",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(OsLoginServiceServer).DeleteSshPublicKey(ctx, req.(*DeleteSshPublicKeyRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _OsLoginService_GetLoginProfile_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(GetLoginProfileRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(OsLoginServiceServer).GetLoginProfile(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/google.cloud.oslogin.v1beta.OsLoginService/GetLoginProfile",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(OsLoginServiceServer).GetLoginProfile(ctx, req.(*GetLoginProfileRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _OsLoginService_GetSshPublicKey_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(GetSshPublicKeyRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(OsLoginServiceServer).GetSshPublicKey(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/google.cloud.oslogin.v1beta.OsLoginService/GetSshPublicKey",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(OsLoginServiceServer).GetSshPublicKey(ctx, req.(*GetSshPublicKeyRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _OsLoginService_ImportSshPublicKey_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(ImportSshPublicKeyRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(OsLoginServiceServer).ImportSshPublicKey(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/google.cloud.oslogin.v1beta.OsLoginService/ImportSshPublicKey",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(OsLoginServiceServer).ImportSshPublicKey(ctx, req.(*ImportSshPublicKeyRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _OsLoginService_UpdateSshPublicKey_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(UpdateSshPublicKeyRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(OsLoginServiceServer).UpdateSshPublicKey(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/google.cloud.oslogin.v1beta.OsLoginService/UpdateSshPublicKey",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(OsLoginServiceServer).UpdateSshPublicKey(ctx, req.(*UpdateSshPublicKeyRequest))
	}
	return interceptor(ctx, in, info, handler)
}

var _OsLoginService_serviceDesc = grpc.ServiceDesc{
	ServiceName: "google.cloud.oslogin.v1beta.OsLoginService",
	HandlerType: (*OsLoginServiceServer)(nil),
	Methods: []grpc.MethodDesc{
		{
			MethodName: "DeletePosixAccount",
			Handler:    _OsLoginService_DeletePosixAccount_Handler,
		},
		{
			MethodName: "DeleteSshPublicKey",
			Handler:    _OsLoginService_DeleteSshPublicKey_Handler,
		},
		{
			MethodName: "GetLoginProfile",
			Handler:    _OsLoginService_GetLoginProfile_Handler,
		},
		{
			MethodName: "GetSshPublicKey",
			Handler:    _OsLoginService_GetSshPublicKey_Handler,
		},
		{
			MethodName: "ImportSshPublicKey",
			Handler:    _OsLoginService_ImportSshPublicKey_Handler,
		},
		{
			MethodName: "UpdateSshPublicKey",
			Handler:    _OsLoginService_UpdateSshPublicKey_Handler,
		},
	},
	Streams:  []grpc.StreamDesc{},
	Metadata: "google/cloud/oslogin/v1beta/oslogin.proto",
}
