blob: 19acd720e7156a46c28f31b59669b74d3dcf6b0a [file] [log] [blame]
/*
Copyright 2017 the original author or authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package main
import (
"flag"
"fmt"
"log"
"net"
"net/http"
"os"
"strings"
"gerrit.opencord.org/abstract-olt/api"
"gerrit.opencord.org/abstract-olt/internal/pkg/settings"
"github.com/grpc-ecosystem/grpc-gateway/runtime"
"golang.org/x/net/context"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/metadata"
)
// private type for Context keys
type contextKey int
const (
clientIDKey contextKey = iota
)
/*
GetLogger - returns the logger
*/
func credMatcher(headerName string) (mdName string, ok bool) {
if headerName == "Login" || headerName == "Password" {
return headerName, true
}
return "", false
}
// authenticateAgent check the client credentials
func authenticateClient(ctx context.Context, s *api.Server) (string, error) {
if md, ok := metadata.FromIncomingContext(ctx); ok {
clientLogin := strings.Join(md["login"], "")
clientPassword := strings.Join(md["password"], "")
if clientLogin != "john" {
return "", fmt.Errorf("unknown user %s", clientLogin)
}
if clientPassword != "doe" {
return "", fmt.Errorf("bad password %s", clientPassword)
}
log.Printf("authenticated client: %s", clientLogin)
return "42", nil
}
return "", fmt.Errorf("missing credentials")
}
// unaryInterceptor call authenticateClient with current context
func unaryInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
s, ok := info.Server.(*api.Server)
if !ok {
return nil, fmt.Errorf("unable to cast server")
}
clientID, err := authenticateClient(ctx, s)
if err != nil {
return nil, err
}
ctx = context.WithValue(ctx, clientIDKey, clientID)
return handler(ctx, req)
}
func startGRPCServer(address, certFile, keyFile string) error {
// create a listener on TCP port
lis, err := net.Listen("tcp", address)
if err != nil {
return fmt.Errorf("failed to listen: %v", err)
}
// create a server instance
s := api.Server{}
// Create the TLS credentials
creds, err := credentials.NewServerTLSFromFile(certFile, keyFile)
if err != nil {
return fmt.Errorf("could not load TLS keys: %s", err)
}
// Create an array of gRPC options with the credentials
opts := []grpc.ServerOption{grpc.Creds(creds),
grpc.UnaryInterceptor(unaryInterceptor)}
// create a gRPC server object
grpcServer := grpc.NewServer(opts...)
// attach the Ping service to the server
api.RegisterAddChassisServer(grpcServer, &s)
api.RegisterAddOLTChassisServer(grpcServer, &s)
// start the server
log.Printf("starting HTTP/2 gRPC server on %s", address)
if err := grpcServer.Serve(lis); err != nil {
return fmt.Errorf("failed to serve: %s", err)
}
return nil
}
func startRESTServer(address, grpcAddress, certFile string) error {
ctx := context.Background()
ctx, cancel := context.WithCancel(ctx)
defer cancel()
mux := runtime.NewServeMux(runtime.WithIncomingHeaderMatcher(credMatcher))
creds, err := credentials.NewClientTLSFromFile(certFile, "")
if err != nil {
return fmt.Errorf("could not load TLS certificate: %s", err)
}
// Setup the client gRPC options
opts := []grpc.DialOption{grpc.WithTransportCredentials(creds)}
err = api.RegisterAddChassisHandlerFromEndpoint(ctx, mux, grpcAddress, opts)
_ = api.RegisterAddOLTChassisHandlerFromEndpoint(ctx, mux, grpcAddress, opts)
if err != nil {
return fmt.Errorf("could not register service Ping: %s", err)
}
log.Printf("starting HTTP/1.1 REST server on %s", address)
http.ListenAndServe(address, mux)
return nil
}
func main() {
debugPtr := flag.Bool("d", false, "Log Level Debug")
flag.Parse()
settings.SetDebug(*debugPtr)
file, err := os.OpenFile("AbstractOLT.log", 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())
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"
// fire the gRPC server in a goroutine
go func() {
err := startGRPCServer(grpcAddress, certFile, keyFile)
if err != nil {
log.Fatalf("failed to start gRPC server: %s", err)
}
}()
// fire the REST server in a goroutine
go func() {
err := startRESTServer(restAddress, grpcAddress, certFile)
if err != nil {
log.Fatalf("failed to start gRPC server: %s", err)
}
}()
// infinite loop
log.Printf("Entering infinite loop")
select {}
fmt.Println("AbstractOLT")
}