VOL-291 : PON simulator refactoring for cluster integration

- Added ponsim build target in Makefile
- Added new option to vcore to select comm type with ponsim
- Modified all proto files to include destination go package

Amendments:

- Clean up based on review comments
- Properly close GRPC connections in ponsim_olt adapter
- Added voltha namespace to some k8s templates

Change-Id: I2f349fa7b3550a8a8cc8fc676cc896f33fbb9372
diff --git a/ponsim/v2/ponsim.go b/ponsim/v2/ponsim.go
new file mode 100644
index 0000000..fad0972
--- /dev/null
+++ b/ponsim/v2/ponsim.go
@@ -0,0 +1,289 @@
+package main
+
+import (
+	"context"
+	"flag"
+	"fmt"
+	"github.com/opencord/voltha/ponsim/v2/common"
+	"github.com/opencord/voltha/ponsim/v2/core"
+	"github.com/opencord/voltha/ponsim/v2/grpc"
+	"log"
+	"os"
+	"os/signal"
+	"path"
+)
+
+// TODO: Cleanup logs
+
+const (
+	default_name           = "PON"
+	default_grpc_port      = 50060
+	default_grpc_addr      = ""
+	default_device_type    = "OLT"
+	default_api_type       = "PONSIM"
+	default_internal_if    = "eth0"
+	default_external_if    = "eth1"
+	default_onus           = 1
+	default_alarm_sim      = false
+	default_alarm_freq     = 60
+	default_quiet          = false
+	default_verbose        = false
+	default_no_banner      = false
+	default_parent_addr    = "olt"
+	default_parent_port    = 50060
+	default_vcore_endpoint = "vcore"
+	default_fluentd_host   = ""
+
+	default_snapshot_len = 65535
+	default_promiscuous  = false
+
+	default_voltha_key  = "pki/voltha.key"
+	default_voltha_cert = "pki/voltha.crt"
+	default_voltha_ca   = "pki/voltha-CA.pem"
+)
+
+var (
+	voltha_base = os.Getenv("VOLTHA_BASE")
+	certs       *grpc.GrpcSecurity
+
+	name           string = default_name + "_" + device_type
+	grpc_port      int    = default_grpc_port
+	grpc_addr      string = default_grpc_addr
+	device_type    string = default_device_type
+	api_type       string = default_api_type
+	internal_if    string = default_internal_if
+	external_if    string = default_external_if
+	onus           int    = default_onus
+	alarm_sim      bool   = default_alarm_sim
+	alarm_freq     int    = default_alarm_freq
+	quiet          bool   = default_quiet
+	verbose        bool   = default_verbose
+	no_banner      bool   = default_no_banner
+	voltha_key     string = default_voltha_key
+	voltha_cert    string = default_voltha_cert
+	voltha_ca      string = default_voltha_ca
+	parent_addr    string = default_parent_addr
+	parent_port    int    = default_parent_port
+	vcore_endpoint string = default_vcore_endpoint
+	fluentd_host   string = default_fluentd_host
+
+	snapshot_len int32 = default_snapshot_len
+	promiscuous  bool  = default_promiscuous
+)
+
+func init() {
+	parseArgs()
+
+	// Enable fluentd support
+	if fluentd_host != "" {
+		common.Logger().SetFluentd(fluentd_host)
+	}
+
+	// Print banner unless no_banner is specified
+	if !no_banner {
+		printBanner()
+	}
+}
+
+func parseArgs() {
+	var help string
+
+	help = fmt.Sprintf("Name of the PON device")
+	flag.StringVar(&grpc_addr, "name", default_name, help)
+
+	help = fmt.Sprintf("Address used to establish GRPC server connection")
+	flag.StringVar(&grpc_addr, "grpc_addr", default_grpc_addr, help)
+
+	help = fmt.Sprintf("Port used to establish GRPC server connection")
+	flag.IntVar(&grpc_port, "grpc_port", default_grpc_port, help)
+
+	help = fmt.Sprintf("Type of device to simulate (OLT or ONU)")
+	flag.StringVar(&device_type, "device_type", default_device_type, help)
+
+	help = fmt.Sprintf("Type of API used to communicate with devices (PONSIM or BAL)")
+	flag.StringVar(&api_type, "api_type", default_api_type, help)
+
+	help = fmt.Sprintf("Internal Communication Interface for read/write network traffic")
+	flag.StringVar(&internal_if, "internal_if", default_internal_if, help)
+
+	help = fmt.Sprintf("External Communication Interface for read/write network traffic")
+	flag.StringVar(&external_if, "external_if", default_external_if, help)
+
+	help = fmt.Sprintf("Enable promiscuous mode on network interfaces")
+	flag.BoolVar(&promiscuous, "promiscuous", default_promiscuous, help)
+
+	help = fmt.Sprintf("Number of ONUs to simulate")
+	flag.IntVar(&onus, "onus", default_onus, help)
+
+	help = fmt.Sprintf("Suppress debug and info logs")
+	flag.BoolVar(&quiet, "quiet", default_quiet, help)
+
+	help = fmt.Sprintf("Enable verbose logging")
+	flag.BoolVar(&verbose, "verbose", default_verbose, help)
+
+	help = fmt.Sprintf("Omit startup banner log lines")
+	flag.BoolVar(&no_banner, "no_banner", default_no_banner, help)
+
+	help = fmt.Sprintf("Enable generation of simulated alarms")
+	flag.BoolVar(&alarm_sim, "alarm_sim", default_alarm_sim, help)
+
+	help = fmt.Sprintf("Frequency of simulated alarms (in seconds)")
+	flag.IntVar(&alarm_freq, "alarm_freq", default_alarm_freq, help)
+
+	help = fmt.Sprintf("Address of OLT to connect to")
+	flag.StringVar(&parent_addr, "parent_addr", default_parent_addr, help)
+
+	help = fmt.Sprintf("Port of OLT to connect to")
+	flag.IntVar(&parent_port, "parent_port", default_parent_port, help)
+
+	help = fmt.Sprintf("Voltha core endpoint address")
+	flag.StringVar(&vcore_endpoint, "vcore_endpoint", default_vcore_endpoint, help)
+
+	help = fmt.Sprintf("Fluentd host address")
+	flag.StringVar(&fluentd_host, "fluentd", default_fluentd_host, help)
+
+	flag.Parse()
+}
+
+func printBanner() {
+	log.Println("    ____  ____  _   _______ ______  ___")
+	log.Println("   / __ \\/ __ \\/ | / / ___//  _/  |/  /")
+	log.Println("  / /_/ / / / /  |/ /\\__ \\ / // /|_/ / ")
+	log.Println(" / ____/ /_/ / /|  /___/ // // /  / /  ")
+	log.Println("/_/    \\____/_/ |_//____/___/_/  /_/  ")
+
+	switch device_type {
+	case "OLT":
+		printOltBanner()
+	case "ONU":
+		printOnuBanner()
+	}
+
+	log.Println("(to stop: press Ctrl-C)")
+}
+func printOltBanner() {
+	log.Println("   ____  __  ______")
+	log.Println("  / __ \\/ / /_  __/")
+	log.Println(" / / / / /   / /   ")
+	log.Println("/ /_/ / /___/ /    ")
+	log.Println("\\____/_____/_/     ")
+}
+func printOnuBanner() {
+	log.Println("   ____  _   ____  __")
+	log.Println("  / __ \\/ | / / / / /")
+	log.Println(" / / / /  |/ / / / / ")
+	log.Println("/ /_/ / /|  / /_/ /  ")
+	log.Println("\\____/_/ |_/\\____/   ")
+}
+
+/*
+-----------------------------------------------------------------
+*/
+type PonSimService struct {
+	device core.PonSimInterface
+	server *grpc.GrpcServer
+}
+
+func (s *PonSimService) Start(ctx context.Context) {
+	// GRPC server needs to be secure.
+	// Otherwise communication between adapter and simulator does not occur
+	s.server = grpc.NewGrpcServer(s.device.GetAddress(), s.device.GetPort(), certs, true)
+
+	// Add GRPC services
+	s.server.AddCommonService(s.device)
+	s.server.AddPonSimService(s.device)
+
+	// Add OLT specific services
+	if device_type == core.OLT.String() {
+		s.server.AddOltService(s.device)
+	}
+
+	// Add XPON services unless using BAL
+	if api_type == core.PONSIM.String() {
+		s.server.AddXPonService()
+	} else {
+		s.server.AddBalService()
+	}
+
+	// Start the GRPC server
+	go s.server.Start(ctx)
+
+	// Start the PON device
+	go s.device.Start(ctx)
+}
+
+func (s *PonSimService) Stop(ctx context.Context) {
+	// Stop PON device
+	s.device.Stop(ctx)
+
+	// Stop GRPC server
+	s.server.Stop()
+}
+
+func main() {
+	var device core.PonSimInterface
+
+	// Init based on type of device
+	// Construct OLT/ONU object and pass it down
+	certs = &grpc.GrpcSecurity{
+		CertFile: path.Join(voltha_base, voltha_cert),
+		KeyFile:  path.Join(voltha_base, voltha_key),
+		CaFile:   path.Join(voltha_base, voltha_ca),
+	}
+
+	// Initialize device with common parameters
+	pon := core.PonSimDevice{
+		Name:        name,
+		ExternalIf:  external_if,
+		InternalIf:  internal_if,
+		Promiscuous: promiscuous,
+		SnapshotLen: snapshot_len,
+		Address:     grpc_addr,
+		Port:        int32(grpc_port),
+		AlarmsOn:    alarm_sim,
+		AlarmsFreq:  alarm_freq,
+		Counter:     core.NewPonSimMetricCounter(name),
+
+		// TODO: pass certificates
+		//GrpcSecurity: certs,
+	}
+
+	switch device_type {
+	case core.OLT.String():
+		device = core.NewPonSimOltDevice(pon)
+		device.(*core.PonSimOltDevice).MaxOnuCount = onus
+		device.(*core.PonSimOltDevice).VCoreEndpoint = vcore_endpoint
+
+	case core.ONU.String():
+		device = core.NewPonSimOnuDevice(pon)
+		device.(*core.PonSimOnuDevice).ParentAddress = parent_addr
+		device.(*core.PonSimOnuDevice).ParentPort = int32(parent_port)
+
+	default:
+		log.Println("Unknown device type")
+	}
+
+	ps := PonSimService{device: device}
+
+	ctx, cancel := context.WithCancel(context.Background())
+	defer cancel()
+
+	ps.Start(ctx)
+
+	signals := make(chan os.Signal, 1)
+	signal.Notify(signals, os.Interrupt)
+
+	doneCh := make(chan struct{})
+
+	go func() {
+		for {
+			select {
+			case <-signals:
+				log.Println("Interrupt was detected")
+				doneCh <- struct{}{}
+			}
+		}
+	}()
+
+	<-doneCh
+}