SEBA-256
Added cmd line switches to AbstractOLT and Client
Change-Id: Ib55e1bf62e90ee49508073c9fdf1b50ae6d8ba64
diff --git a/api/abstract_olt_api.proto b/api/abstract_olt_api.proto
index 6da61c8..fb4aee7 100644
--- a/api/abstract_olt_api.proto
+++ b/api/abstract_olt_api.proto
@@ -16,6 +16,13 @@
package api;
import "google/api/annotations.proto";
+message EchoMessage{
+ string Ping =1;
+}
+message EchoReplyMessage{
+ string Pong =1;
+}
+
message AddChassisMessage{
string CLLI =1;
string VCoreIP =2;
@@ -75,6 +82,12 @@
bool Success=1;
}
service AbstractOLT{
+ rpc Echo(EchoMessage) returns (EchoReplyMessage){
+ option(google.api.http)={
+ post:"/v1/Echo"
+ body:"*"
+ };
+ }
rpc CreateChassis(AddChassisMessage) returns (AddChassisReturn) {
option(google.api.http) = {
post: "/v1/CreateAbstractChassis"
diff --git a/api/handler.go b/api/handler.go
index bb1a9b3..54115a6 100644
--- a/api/handler.go
+++ b/api/handler.go
@@ -36,6 +36,12 @@
type Server struct {
}
+func (s *Server) Echo(ctx context.Context, in *EchoMessage) (*EchoReplyMessage, error) {
+ ping := in.GetPing()
+ pong := EchoReplyMessage{Pong: ping}
+ return &pong, nil
+}
+
/*
CreateChassis - allocates a new Chassis struct and stores it in chassisMap
*/
diff --git a/client/main.go b/client/main.go
index 884274b..af87ec7 100644
--- a/client/main.go
+++ b/client/main.go
@@ -22,6 +22,7 @@
"fmt"
"log"
"runtime/debug"
+ "strings"
"gerrit.opencord.org/abstract-olt/api"
"google.golang.org/grpc"
@@ -29,6 +30,8 @@
)
func main() {
+ echo := flag.Bool("e", false, "echo")
+ message := flag.String("message", "ping", "message to be echoed back")
create := flag.Bool("c", false, "create?")
addOlt := flag.Bool("s", false, "addOlt?")
provOnt := flag.Bool("o", false, "provisionOnt?")
@@ -46,30 +49,56 @@
port := flag.Uint("port", 1, "port number 1-16 to provision ont to")
ont := flag.Uint("ont", 1, "ont number 1-64")
serial := flag.String("serial", "", "serial number of ont")
+ useSsl := flag.Bool("ssl", false, "use ssl")
+ useAuth := flag.Bool("auth", false, "use auth")
+ crtFile := flag.String("cert", "cert/server.crt", "Public cert for server to establish tls session")
+ serverAddressPort := flag.String("server", "localhost:7777", "address and port of AbstractOLT server")
+ fqdn := flag.String("fqdn", "", "FQDN of the service to match what is in server.crt")
flag.Parse()
+ if *useSsl {
+ if *fqdn == "" {
+ fqdn = &(strings.Split(*serverAddressPort, ":")[0])
+ fmt.Printf("using %s as the FQDN for the AbstractOLT server", *fqdn)
+ }
+ }
- if (*create && *addOlt) || (*create && *provOnt) || (*addOlt && *provOnt) {
+ if (*echo && *addOlt) || (*echo && *create) || (*echo && *provOnt) || (*create && *addOlt) || (*create && *provOnt) || (*addOlt && *provOnt) {
fmt.Println("You can only call one method at a time")
usage()
return
}
- if !(*create || *provOnt || *addOlt) {
+ if !(*create || *provOnt || *addOlt || *echo) {
fmt.Println("You didn't specify an operation to perform")
usage()
return
}
var conn *grpc.ClientConn
- creds, err := credentials.NewClientTLSFromFile("cert/server.crt", "AbstractOLT.dev.atl.foundry.att.com")
- if err != nil {
- log.Fatalf("could not load tls cert: %s", err)
- }
+ var err error
+
// Setup the login/pass
auth := Authentication{
Login: "john",
Password: "doe",
}
- conn, err = grpc.Dial(":7777", grpc.WithTransportCredentials(creds), grpc.WithPerRPCCredentials(&auth))
+ if *useSsl && *useAuth {
+
+ creds, err := credentials.NewClientTLSFromFile(*crtFile, *fqdn)
+ conn, err = grpc.Dial(*serverAddressPort, grpc.WithTransportCredentials(creds), grpc.WithPerRPCCredentials(&auth))
+ if err != nil {
+ log.Fatalf("could not load tls cert: %s", err)
+ }
+ } else if *useSsl {
+ creds, err := credentials.NewClientTLSFromFile("cert/server.crt", *fqdn)
+ conn, err = grpc.Dial(*serverAddressPort, grpc.WithTransportCredentials(creds))
+ if err != nil {
+ log.Fatalf("could not load tls cert: %s", err)
+ }
+ } else if *useAuth {
+ conn, err = grpc.Dial(*serverAddressPort, grpc.WithInsecure(), grpc.WithPerRPCCredentials(&auth))
+ } else {
+ conn, err = grpc.Dial(*serverAddressPort, grpc.WithInsecure())
+ }
if err != nil {
log.Fatalf("did not connect: %s", err)
}
@@ -82,10 +111,10 @@
addOltChassis(c, clli, oltAddress, oltPort, name, driver, oltType)
} else if *provOnt {
provisionONT(c, clli, slot, port, ont, serial)
- } else {
+ } else if *echo {
+ ping(c, *message)
}
- fmt.Println("TODO - Do something")
}
// Authentication holds the login/password
@@ -106,6 +135,15 @@
func (a *Authentication) RequireTransportSecurity() bool {
return true
}
+func ping(c api.AbstractOLTClient, message string) error {
+ response, err := c.Echo(context.Background(), &api.EchoMessage{Ping: message})
+ if err != nil {
+ fmt.Printf("Error when calling Echo: %s", err)
+ return err
+ }
+ log.Printf("Response from server: %s", response.GetPong())
+ return nil
+}
func createChassis(c api.AbstractOLTClient, clli *string, xosAddress *string, xosPort *uint, rack *uint, shelf *uint) error {
fmt.Println("Calling Create Chassis")
@@ -169,8 +207,15 @@
}
func usage() {
var output = `
- Usage ./client -[methodFlag] params
- methFlags:
+ Usage ./client -server=[serverAddress:port] -[methodFlag] params
+ ./client -ssl -fqdn=FQDN_OF_ABSTRACT_OLT_SERVER.CRT -cert PATH_TO_SERVER.CRT -server=[serverAddress:port] -[methodFlag] params : use ssl
+ ./client -auth -server=[serverAddress:port] -[methodFlag] params : Authenticate session
+
+ methodFlags:
+ -e echo # used to test connectivity to server NOOP
+ params:
+ -message string to be echoed back from the server
+ e.g. ./client -server=localhost:7777 -e -message MESSAGE_TO_BE_ECHOED
-c create chassis
params:
-clli CLLI_NAME
@@ -178,7 +223,7 @@
-xos_port XOS_TOSCA_LISTEN_PORT
-rack [optional default 1]
-shelf [optional default 1]
- e.g. ./client -c -clli MY_CLLI -xos_address 192.168.0.1 -xos_port 30007 -rack 1 -shelf 1
+ e.g. ./client -server=localhost:7777 -c -clli MY_CLLI -xos_address 192.168.0.1 -xos_port 30007 -rack 1 -shelf 1
-s add physical olt chassis to chassis
params:
-clli CLLI_NAME - identifies abstract chassis to assign olt chassis to
@@ -187,7 +232,7 @@
-name - OLT_NAME internal human readable name to identify OLT_CHASSIS
-driver [openolt,asfvolt16,adtran,tibits] - used to tell XOS which driver should be used to manange chassis
-type [edgecore,adtran,tibit] - used to tell AbstractOLT how many ports are available on olt chassis
- e.g. ./client -s -clli MY_CLLI -olt_address 192.168.1.100 -olt_port=9191 -name=slot1 -driver=openolt -type=adtran
+ e.g. ./client -server abstractOltHost:7777 -s -clli MY_CLLI -olt_address 192.168.1.100 -olt_port=9191 -name=slot1 -driver=openolt -type=adtran
-o provision ont - adds ont to whitelist in XOS on a specific port on a specific olt chassis based on abstract -> phyisical mapping
params:
-clli CLLI_NAME
@@ -195,7 +240,7 @@
-port OLT_PORT_NUMBER [1-16]
-ont ONT_NUMBER [1-64]
-serial ONT_SERIAL_NUM
- e.g. ./client -o -clli=MY_CLLI -slot=1 -port=1 -ont=22 -serial=aer900jasdf `
+ e.g. ./client -server=localhost:7777 -o -clli=MY_CLLI -slot=1 -port=1 -ont=22 -serial=aer900jasdf `
fmt.Println(output)
}
diff --git a/cmd/AbstractOLT/AbstractOLT.go b/cmd/AbstractOLT/AbstractOLT.go
index 57ef9cd..8527ff6 100644
--- a/cmd/AbstractOLT/AbstractOLT.go
+++ b/cmd/AbstractOLT/AbstractOLT.go
@@ -37,6 +37,10 @@
// private type for Context keys
type contextKey int
+var useSsl *bool
+var useAuthentication *bool
+var certDirectory *string
+
const (
clientIDKey contextKey = iota
)
@@ -53,6 +57,7 @@
// authenticateAgent check the client credentials
func authenticateClient(ctx context.Context, s *api.Server) (string, error) {
+ //TODO if we decide to handle Authentication with AbstractOLT this will need to be bound to an authentication service
if md, ok := metadata.FromIncomingContext(ctx); ok {
clientLogin := strings.Join(md["login"], "")
clientPassword := strings.Join(md["password"], "")
@@ -86,9 +91,13 @@
}
func startGRPCServer(address, certFile, keyFile string) error {
+ if settings.GetDebug() {
+ log.Printf("startGRPCServer(LisenAddress:%s,CertFile:%s,KeyFile:%s\n", address, certFile, keyFile)
+ }
// create a listener on TCP port
lis, err := net.Listen("tcp", address)
if err != nil {
+ log.Printf("startGRPCServer failed to start with %v\n", err)
return fmt.Errorf("failed to listen: %v", err)
}
@@ -102,8 +111,17 @@
}
// Create an array of gRPC options with the credentials
- opts := []grpc.ServerOption{grpc.Creds(creds),
- grpc.UnaryInterceptor(unaryInterceptor)}
+ var opts []grpc.ServerOption
+ if *useSsl && *useAuthentication {
+ opts = []grpc.ServerOption{grpc.Creds(creds),
+ grpc.UnaryInterceptor(unaryInterceptor)}
+ } else if *useAuthentication {
+ opts = []grpc.ServerOption{grpc.UnaryInterceptor(unaryInterceptor)}
+ } else if *useSsl {
+ opts = []grpc.ServerOption{grpc.Creds(creds)}
+ } else {
+ opts = []grpc.ServerOption{}
+ }
// create a gRPC server object
grpcServer := grpc.NewServer(opts...)
@@ -120,11 +138,19 @@
return nil
}
func startRESTServer(address, grpcAddress, certFile string) error {
+ if settings.GetDebug() {
+ log.Printf("startRESTServer(Address:%s, GRPCAddress:%s,Cert File:%s\n", address, grpcAddress, certFile)
+ }
ctx := context.Background()
ctx, cancel := context.WithCancel(ctx)
defer cancel()
+ var mux *runtime.ServeMux
- mux := runtime.NewServeMux(runtime.WithIncomingHeaderMatcher(credMatcher))
+ if *useAuthentication {
+ mux = runtime.NewServeMux(runtime.WithIncomingHeaderMatcher(credMatcher))
+ } else {
+ mux = runtime.NewServeMux()
+ }
creds, err := credentials.NewClientTLSFromFile(certFile, "")
if err != nil {
return fmt.Errorf("could not load TLS certificate: %s", err)
@@ -144,21 +170,51 @@
}
func main() {
debugPtr := flag.Bool("d", false, "Log Level Debug")
- flag.Parse()
- settings.SetDebug(*debugPtr)
+ useAuthentication = flag.Bool("a", false, "Use Authentication")
+ useSsl = flag.Bool("s", false, "Use SSL")
+ certDirectory = flag.String("cert_dir", "cert", "Directory where key files exist")
+ listenAddress := flag.String("listenAddress", "localhost", "IP Address to listen on")
+ grpcPort := flag.String("grpc_port", "7777", "Port to listen for GRPC")
+ restPort := flag.String("rest_port", "7778", "Port to listen for Rest Server")
+ logFile := flag.String("log_file", "AbstractOLT.log", "Name of the LogFile to write to")
+ h := flag.Bool("h", false, "Show usage")
+ help := flag.Bool("help", false, "Show usage")
- file, err := os.OpenFile("AbstractOLT.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
+ flag.Parse()
+
+ if *help || *h {
+ var usage = `./AbstractOLT -d [default false] : Runs in Debug mode
+Params:
+ -s [default false] -cert_dir [default $WORKING_DIR/cert] DIR : Runs in SSL mode with server.crt and server.key found in DIR
+ -a [default false] : Run in Authentication mode currently very basic
+ -listenAddress IP_ADDRESS [default localhost] -grpc_port [default 7777] PORT1 -rest_port [default 7778] PORT2: Listen for grpc on IP_ADDRESS:PORT1 and rest on IP_ADDRESS:PORT2
+ -log_file [default $WORKING_DIR/AbstractOLT.log] LOG_FILE
+ -h(elp) print this usage
+`
+ fmt.Println(usage)
+ return
+ }
+ settings.SetDebug(*debugPtr)
+ fmt.Println("Startup Params: debug:", *debugPtr, " Authentication:", *useAuthentication, " SSL:", *useSsl, "Cert Directory", *certDirectory,
+ "ListenAddress:", *listenAddress, " grpc port:", *grpcPort, " rest port:", *restPort, "Logging to ", *logFile)
+
+ file, err := os.OpenFile(*logFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
if err != nil {
log.Fatalln("Failed to open log file", file, ":", err)
}
log.SetOutput(file)
log.SetFlags(log.Ldate | log.Ltime | log.Lmicroseconds | log.Lshortfile)
log.Printf("Setting Debug to %t\n", settings.GetDebug())
+ if settings.GetDebug() {
+ log.Println("Startup Params: debug:", *debugPtr, " Authentication:", *useAuthentication, " SSL:", *useSsl, "Cert Directory", *certDirectory,
+ "ListenAddress:", *listenAddress, " grpc port:", *grpcPort, " rest port:", *restPort, "Logging to ", *logFile)
+ }
- grpcAddress := fmt.Sprintf("%s:%d", "AbstractOLT.dev.atl.foundry.att.com", 7777)
- restAddress := fmt.Sprintf("%s:%d", "AbstractOLT.dev.atl.foundry.att.com", 7778)
- certFile := "cert/server.crt"
- keyFile := "cert/server.key"
+ grpcAddress := fmt.Sprintf("%s:%s", *listenAddress, *grpcPort)
+ restAddress := fmt.Sprintf("%s:%s", *listenAddress, *restPort)
+
+ certFile := fmt.Sprintf("%s/server.crt", *certDirectory)
+ keyFile := fmt.Sprintf("%s/server.key", *certDirectory)
// fire the gRPC server in a goroutine
go func() {
@@ -179,5 +235,6 @@
// infinite loop
log.Printf("Entering infinite loop")
select {}
+ //TODO publish periodic stats etc
fmt.Println("AbstractOLT")
}