// Code generated by protoc-gen-go. DO NOT EDIT.
// source: proxy.proto

package proto

import (
	fmt "fmt"
	proto "github.com/golang/protobuf/proto"
	context "golang.org/x/net/context"
	grpc "google.golang.org/grpc"
	math "math"
)

// 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.ProtoPackageIsVersion2 // please upgrade the proto package

type GetKVMDataRequest struct {
	BladeNum             int64    `protobuf:"varint,1,opt,name=blade_num,json=bladeNum,proto3" json:"blade_num,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

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

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

var xxx_messageInfo_GetKVMDataRequest proto.InternalMessageInfo

func (m *GetKVMDataRequest) GetBladeNum() int64 {
	if m != nil {
		return m.BladeNum
	}
	return 0
}

type GetKVMDataResponse struct {
	Arguments            []string `protobuf:"bytes,1,rep,name=arguments,proto3" json:"arguments,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

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

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

var xxx_messageInfo_GetKVMDataResponse proto.InternalMessageInfo

func (m *GetKVMDataResponse) GetArguments() []string {
	if m != nil {
		return m.Arguments
	}
	return nil
}

func init() {
	proto.RegisterType((*GetKVMDataRequest)(nil), "proto.GetKVMDataRequest")
	proto.RegisterType((*GetKVMDataResponse)(nil), "proto.GetKVMDataResponse")
}

func init() { proto.RegisterFile("proxy.proto", fileDescriptor_700b50b08ed8dbaf) }

var fileDescriptor_700b50b08ed8dbaf = []byte{
	// 156 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x2e, 0x28, 0xca, 0xaf,
	0xa8, 0xd4, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x05, 0x53, 0x4a, 0x06, 0x5c, 0x82, 0xee,
	0xa9, 0x25, 0xde, 0x61, 0xbe, 0x2e, 0x89, 0x25, 0x89, 0x41, 0xa9, 0x85, 0xa5, 0xa9, 0xc5, 0x25,
	0x42, 0xd2, 0x5c, 0x9c, 0x49, 0x39, 0x89, 0x29, 0xa9, 0xf1, 0x79, 0xa5, 0xb9, 0x12, 0x8c, 0x0a,
	0x8c, 0x1a, 0xcc, 0x41, 0x1c, 0x60, 0x01, 0xbf, 0xd2, 0x5c, 0x25, 0x23, 0x2e, 0x21, 0x64, 0x1d,
	0xc5, 0x05, 0xf9, 0x79, 0xc5, 0xa9, 0x42, 0x32, 0x5c, 0x9c, 0x89, 0x45, 0xe9, 0xa5, 0xb9, 0xa9,
	0x79, 0x25, 0xc5, 0x12, 0x8c, 0x0a, 0xcc, 0x1a, 0x9c, 0x41, 0x08, 0x01, 0x23, 0x5f, 0x2e, 0x0e,
	0x67, 0x5f, 0xe7, 0x00, 0x90, 0xf5, 0x42, 0x8e, 0x5c, 0x5c, 0x08, 0xfd, 0x42, 0x12, 0x10, 0xe7,
	0xe8, 0x61, 0x38, 0x42, 0x4a, 0x12, 0x8b, 0x0c, 0xc4, 0xb2, 0x24, 0x36, 0xb0, 0x8c, 0x31, 0x20,
	0x00, 0x00, 0xff, 0xff, 0x09, 0x00, 0x2b, 0x54, 0xd1, 0x00, 0x00, 0x00,
}

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

// 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.SupportPackageIsVersion4

// CMCProxyClient is the client API for CMCProxy service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type CMCProxyClient interface {
	GetKVMData(ctx context.Context, in *GetKVMDataRequest, opts ...grpc.CallOption) (*GetKVMDataResponse, error)
}

type cMCProxyClient struct {
	cc *grpc.ClientConn
}

func NewCMCProxyClient(cc *grpc.ClientConn) CMCProxyClient {
	return &cMCProxyClient{cc}
}

func (c *cMCProxyClient) GetKVMData(ctx context.Context, in *GetKVMDataRequest, opts ...grpc.CallOption) (*GetKVMDataResponse, error) {
	out := new(GetKVMDataResponse)
	err := c.cc.Invoke(ctx, "/proto.CMCProxy/GetKVMData", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

// CMCProxyServer is the server API for CMCProxy service.
type CMCProxyServer interface {
	GetKVMData(context.Context, *GetKVMDataRequest) (*GetKVMDataResponse, error)
}

func RegisterCMCProxyServer(s *grpc.Server, srv CMCProxyServer) {
	s.RegisterService(&_CMCProxy_serviceDesc, srv)
}

func _CMCProxy_GetKVMData_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(GetKVMDataRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(CMCProxyServer).GetKVMData(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/proto.CMCProxy/GetKVMData",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(CMCProxyServer).GetKVMData(ctx, req.(*GetKVMDataRequest))
	}
	return interceptor(ctx, in, info, handler)
}

var _CMCProxy_serviceDesc = grpc.ServiceDesc{
	ServiceName: "proto.CMCProxy",
	HandlerType: (*CMCProxyServer)(nil),
	Methods: []grpc.MethodDesc{
		{
			MethodName: "GetKVMData",
			Handler:    _CMCProxy_GetKVMData_Handler,
		},
	},
	Streams:  []grpc.StreamDesc{},
	Metadata: "proxy.proto",
}
