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

/*
Package config is a generated protocol buffer package.

It is generated from these files:
	config.proto

It has these top-level messages:
	Config
	Switch
	SwitchPort
*/
package config

import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import 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 Switch_Connector int32

const (
	Switch_CONNECTOR_INVALID Switch_Connector = 0
	Switch_CONNECTOR_M6220   Switch_Connector = 1
	Switch_CONNECTOR_ARISTA  Switch_Connector = 2
)

var Switch_Connector_name = map[int32]string{
	0: "CONNECTOR_INVALID",
	1: "CONNECTOR_M6220",
	2: "CONNECTOR_ARISTA",
}
var Switch_Connector_value = map[string]int32{
	"CONNECTOR_INVALID": 0,
	"CONNECTOR_M6220":   1,
	"CONNECTOR_ARISTA":  2,
}

func (x Switch_Connector) String() string {
	return proto.EnumName(Switch_Connector_name, int32(x))
}
func (Switch_Connector) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{1, 0} }

type Config struct {
	Switch []*Switch `protobuf:"bytes,1,rep,name=switch" json:"switch,omitempty"`
}

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

func (m *Config) GetSwitch() []*Switch {
	if m != nil {
		return m.Switch
	}
	return nil
}

type Switch struct {
	Name        string           `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
	Connector   Switch_Connector `protobuf:"varint,2,opt,name=connector,enum=Switch_Connector" json:"connector,omitempty"`
	Address     string           `protobuf:"bytes,3,opt,name=address" json:"address,omitempty"`
	ManagedPort []*SwitchPort    `protobuf:"bytes,4,rep,name=managed_port,json=managedPort" json:"managed_port,omitempty"`
}

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

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

func (m *Switch) GetConnector() Switch_Connector {
	if m != nil {
		return m.Connector
	}
	return Switch_CONNECTOR_INVALID
}

func (m *Switch) GetAddress() string {
	if m != nil {
		return m.Address
	}
	return ""
}

func (m *Switch) GetManagedPort() []*SwitchPort {
	if m != nil {
		return m.ManagedPort
	}
	return nil
}

type SwitchPort struct {
	Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
}

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

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

func init() {
	proto.RegisterType((*Config)(nil), "Config")
	proto.RegisterType((*Switch)(nil), "Switch")
	proto.RegisterType((*SwitchPort)(nil), "SwitchPort")
	proto.RegisterEnum("Switch_Connector", Switch_Connector_name, Switch_Connector_value)
}

func init() { proto.RegisterFile("config.proto", fileDescriptor0) }

var fileDescriptor0 = []byte{
	// 242 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x90, 0x41, 0x4b, 0xc3, 0x30,
	0x14, 0xc7, 0xcd, 0x36, 0x3a, 0xfa, 0x3a, 0xb4, 0x7b, 0x2a, 0xe4, 0x66, 0xe9, 0xa9, 0x5e, 0xaa,
	0x54, 0xf0, 0x5e, 0xaa, 0x87, 0x82, 0xeb, 0x24, 0x1b, 0x5e, 0x47, 0x4c, 0xe3, 0xdc, 0x61, 0xc9,
	0x48, 0x03, 0x7e, 0x63, 0x3f, 0x87, 0x18, 0x33, 0x73, 0xd9, 0x2d, 0xbf, 0x5f, 0x1e, 0xff, 0x7f,
	0xf2, 0x60, 0x26, 0xb4, 0xfa, 0xd8, 0x6d, 0xcb, 0x83, 0xd1, 0x56, 0xe7, 0xb7, 0x10, 0x35, 0x8e,
	0xf1, 0x06, 0xa2, 0xe1, 0x6b, 0x67, 0xc5, 0x27, 0x25, 0xd9, 0xb8, 0x48, 0xaa, 0x69, 0xb9, 0x72,
	0xc8, 0xbc, 0xce, 0xbf, 0x09, 0x44, 0x7f, 0x0a, 0x11, 0x26, 0x8a, 0xef, 0x25, 0x25, 0x19, 0x29,
	0x62, 0xe6, 0xce, 0x78, 0x07, 0xb1, 0xd0, 0x4a, 0x49, 0x61, 0xb5, 0xa1, 0xa3, 0x8c, 0x14, 0xe7,
	0xd5, 0xdc, 0x47, 0x94, 0xcd, 0xf1, 0x82, 0x85, 0x19, 0xa4, 0x30, 0xe5, 0x7d, 0x6f, 0xe4, 0x30,
	0xd0, 0xb1, 0xcb, 0x39, 0x22, 0x96, 0x30, 0xdb, 0x73, 0xc5, 0xb7, 0xb2, 0xdf, 0x1c, 0xb4, 0xb1,
	0x74, 0xe2, 0x1e, 0x94, 0xf8, 0xb4, 0x57, 0x6d, 0x2c, 0x4b, 0xfc, 0xc0, 0x2f, 0xe4, 0x0b, 0x88,
	0xff, 0x1b, 0xf0, 0x1a, 0xe6, 0xcd, 0xb2, 0xeb, 0x9e, 0x9b, 0xf5, 0x92, 0x6d, 0xda, 0xee, 0xad,
	0x7e, 0x69, 0x9f, 0xd2, 0x33, 0xbc, 0x84, 0x8b, 0xa0, 0x17, 0x8f, 0x55, 0x75, 0x9f, 0x12, 0xbc,
	0x82, 0x34, 0xc8, 0x9a, 0xb5, 0xab, 0x75, 0x9d, 0x8e, 0xf2, 0x0c, 0x20, 0x34, 0x9d, 0xfa, 0xeb,
	0x7b, 0xe4, 0x96, 0xf7, 0xf0, 0x13, 0x00, 0x00, 0xff, 0xff, 0xe7, 0x8d, 0xb8, 0x1f, 0x4c, 0x01,
	0x00, 0x00,
}
