blob: 2148cc9daf9a4910b3563e61f39af1a321c077f8 [file] [log] [blame]
Author Namea594e632018-08-10 11:33:58 -04001/*
2 Copyright 2017 the original author or authors.
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15*/
16
17package main
18
19import (
20 "flag"
21 "fmt"
22 "log"
23 "net"
24 "net/http"
25 "os"
26 "strings"
27
28 "gerrit.opencord.org/abstract-olt/api"
29 "gerrit.opencord.org/abstract-olt/internal/pkg/settings"
30 "github.com/grpc-ecosystem/grpc-gateway/runtime"
31 "golang.org/x/net/context"
32 "google.golang.org/grpc"
33 "google.golang.org/grpc/credentials"
34 "google.golang.org/grpc/metadata"
35)
36
37// private type for Context keys
38type contextKey int
39
donNewtonAlphab3279ea2018-09-18 15:55:32 -040040var useSsl *bool
41var useAuthentication *bool
42var certDirectory *string
43
Author Namea594e632018-08-10 11:33:58 -040044const (
45 clientIDKey contextKey = iota
46)
47
48/*
49GetLogger - returns the logger
50*/
51func credMatcher(headerName string) (mdName string, ok bool) {
52 if headerName == "Login" || headerName == "Password" {
53 return headerName, true
54 }
55 return "", false
56}
57
58// authenticateAgent check the client credentials
59func authenticateClient(ctx context.Context, s *api.Server) (string, error) {
donNewtonAlphab3279ea2018-09-18 15:55:32 -040060 //TODO if we decide to handle Authentication with AbstractOLT this will need to be bound to an authentication service
Author Namea594e632018-08-10 11:33:58 -040061 if md, ok := metadata.FromIncomingContext(ctx); ok {
62 clientLogin := strings.Join(md["login"], "")
63 clientPassword := strings.Join(md["password"], "")
64
65 if clientLogin != "john" {
66 return "", fmt.Errorf("unknown user %s", clientLogin)
67 }
68 if clientPassword != "doe" {
69 return "", fmt.Errorf("bad password %s", clientPassword)
70 }
71
72 log.Printf("authenticated client: %s", clientLogin)
73 return "42", nil
74 }
75 return "", fmt.Errorf("missing credentials")
76}
77
78// unaryInterceptor call authenticateClient with current context
79func unaryInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
80 s, ok := info.Server.(*api.Server)
81 if !ok {
82 return nil, fmt.Errorf("unable to cast server")
83 }
84 clientID, err := authenticateClient(ctx, s)
85 if err != nil {
86 return nil, err
87 }
88
89 ctx = context.WithValue(ctx, clientIDKey, clientID)
90 return handler(ctx, req)
91}
92
93func startGRPCServer(address, certFile, keyFile string) error {
donNewtonAlphab3279ea2018-09-18 15:55:32 -040094 if settings.GetDebug() {
95 log.Printf("startGRPCServer(LisenAddress:%s,CertFile:%s,KeyFile:%s\n", address, certFile, keyFile)
96 }
Author Namea594e632018-08-10 11:33:58 -040097 // create a listener on TCP port
98 lis, err := net.Listen("tcp", address)
99 if err != nil {
donNewtonAlphab3279ea2018-09-18 15:55:32 -0400100 log.Printf("startGRPCServer failed to start with %v\n", err)
Author Namea594e632018-08-10 11:33:58 -0400101 return fmt.Errorf("failed to listen: %v", err)
102 }
103
104 // create a server instance
105 s := api.Server{}
106
107 // Create the TLS credentials
108 creds, err := credentials.NewServerTLSFromFile(certFile, keyFile)
109 if err != nil {
110 return fmt.Errorf("could not load TLS keys: %s", err)
111 }
112
113 // Create an array of gRPC options with the credentials
donNewtonAlphab3279ea2018-09-18 15:55:32 -0400114 var opts []grpc.ServerOption
115 if *useSsl && *useAuthentication {
116 opts = []grpc.ServerOption{grpc.Creds(creds),
117 grpc.UnaryInterceptor(unaryInterceptor)}
118 } else if *useAuthentication {
119 opts = []grpc.ServerOption{grpc.UnaryInterceptor(unaryInterceptor)}
120 } else if *useSsl {
121 opts = []grpc.ServerOption{grpc.Creds(creds)}
122 } else {
123 opts = []grpc.ServerOption{}
124 }
Author Namea594e632018-08-10 11:33:58 -0400125
126 // create a gRPC server object
127 grpcServer := grpc.NewServer(opts...)
128
129 // attach the Ping service to the server
donNewtonAlpha5234b132018-08-16 14:12:28 -0400130 api.RegisterAbstractOLTServer(grpcServer, &s)
Author Namea594e632018-08-10 11:33:58 -0400131
132 // start the server
133 log.Printf("starting HTTP/2 gRPC server on %s", address)
134 if err := grpcServer.Serve(lis); err != nil {
135 return fmt.Errorf("failed to serve: %s", err)
136 }
137
138 return nil
139}
140func startRESTServer(address, grpcAddress, certFile string) error {
donNewtonAlphab3279ea2018-09-18 15:55:32 -0400141 if settings.GetDebug() {
142 log.Printf("startRESTServer(Address:%s, GRPCAddress:%s,Cert File:%s\n", address, grpcAddress, certFile)
143 }
Author Namea594e632018-08-10 11:33:58 -0400144 ctx := context.Background()
145 ctx, cancel := context.WithCancel(ctx)
146 defer cancel()
donNewtonAlphab3279ea2018-09-18 15:55:32 -0400147 var mux *runtime.ServeMux
Author Namea594e632018-08-10 11:33:58 -0400148
donNewtonAlphab3279ea2018-09-18 15:55:32 -0400149 if *useAuthentication {
150 mux = runtime.NewServeMux(runtime.WithIncomingHeaderMatcher(credMatcher))
151 } else {
152 mux = runtime.NewServeMux()
153 }
Author Namea594e632018-08-10 11:33:58 -0400154 creds, err := credentials.NewClientTLSFromFile(certFile, "")
155 if err != nil {
156 return fmt.Errorf("could not load TLS certificate: %s", err)
157 }
158
159 // Setup the client gRPC options
160 opts := []grpc.DialOption{grpc.WithTransportCredentials(creds)}
donNewtonAlpha5234b132018-08-16 14:12:28 -0400161 err = api.RegisterAbstractOLTHandlerFromEndpoint(ctx, mux, grpcAddress, opts)
Author Namea594e632018-08-10 11:33:58 -0400162 if err != nil {
163 return fmt.Errorf("could not register service Ping: %s", err)
164 }
165
166 log.Printf("starting HTTP/1.1 REST server on %s", address)
167 http.ListenAndServe(address, mux)
168
169 return nil
170}
171func main() {
172 debugPtr := flag.Bool("d", false, "Log Level Debug")
donNewtonAlphab3279ea2018-09-18 15:55:32 -0400173 useAuthentication = flag.Bool("a", false, "Use Authentication")
174 useSsl = flag.Bool("s", false, "Use SSL")
175 certDirectory = flag.String("cert_dir", "cert", "Directory where key files exist")
176 listenAddress := flag.String("listenAddress", "localhost", "IP Address to listen on")
177 grpcPort := flag.String("grpc_port", "7777", "Port to listen for GRPC")
178 restPort := flag.String("rest_port", "7778", "Port to listen for Rest Server")
179 logFile := flag.String("log_file", "AbstractOLT.log", "Name of the LogFile to write to")
180 h := flag.Bool("h", false, "Show usage")
181 help := flag.Bool("help", false, "Show usage")
donNewtonAlphaaf229742018-09-19 13:22:00 -0400182 dummy := flag.Bool("dummy", false, "Run in dummy mode where YAML is not sent to XOS")
Author Namea594e632018-08-10 11:33:58 -0400183
donNewtonAlphab3279ea2018-09-18 15:55:32 -0400184 flag.Parse()
donNewtonAlphaaf229742018-09-19 13:22:00 -0400185 settings.SetDummy(*dummy)
donNewtonAlphab3279ea2018-09-18 15:55:32 -0400186
187 if *help || *h {
188 var usage = `./AbstractOLT -d [default false] : Runs in Debug mode
189Params:
190 -s [default false] -cert_dir [default $WORKING_DIR/cert] DIR : Runs in SSL mode with server.crt and server.key found in DIR
191 -a [default false] : Run in Authentication mode currently very basic
192 -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
193 -log_file [default $WORKING_DIR/AbstractOLT.log] LOG_FILE
194 -h(elp) print this usage
195`
196 fmt.Println(usage)
197 return
198 }
199 settings.SetDebug(*debugPtr)
200 fmt.Println("Startup Params: debug:", *debugPtr, " Authentication:", *useAuthentication, " SSL:", *useSsl, "Cert Directory", *certDirectory,
201 "ListenAddress:", *listenAddress, " grpc port:", *grpcPort, " rest port:", *restPort, "Logging to ", *logFile)
202
203 file, err := os.OpenFile(*logFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
Author Namea594e632018-08-10 11:33:58 -0400204 if err != nil {
205 log.Fatalln("Failed to open log file", file, ":", err)
206 }
207 log.SetOutput(file)
208 log.SetFlags(log.Ldate | log.Ltime | log.Lmicroseconds | log.Lshortfile)
donNewtonAlphaaf229742018-09-19 13:22:00 -0400209 if *dummy {
210 fmt.Println("RUNNING IN DUMMY MODE NO YAML WILL BE SENT TO XOS")
211 log.Println("RUNNING IN DUMMY MODE NO YAML WILL BE SENT TO XOS")
212 }
Author Namea594e632018-08-10 11:33:58 -0400213 log.Printf("Setting Debug to %t\n", settings.GetDebug())
donNewtonAlphab3279ea2018-09-18 15:55:32 -0400214 if settings.GetDebug() {
215 log.Println("Startup Params: debug:", *debugPtr, " Authentication:", *useAuthentication, " SSL:", *useSsl, "Cert Directory", *certDirectory,
216 "ListenAddress:", *listenAddress, " grpc port:", *grpcPort, " rest port:", *restPort, "Logging to ", *logFile)
217 }
Author Namea594e632018-08-10 11:33:58 -0400218
donNewtonAlphab3279ea2018-09-18 15:55:32 -0400219 grpcAddress := fmt.Sprintf("%s:%s", *listenAddress, *grpcPort)
220 restAddress := fmt.Sprintf("%s:%s", *listenAddress, *restPort)
221
222 certFile := fmt.Sprintf("%s/server.crt", *certDirectory)
223 keyFile := fmt.Sprintf("%s/server.key", *certDirectory)
Author Namea594e632018-08-10 11:33:58 -0400224
225 // fire the gRPC server in a goroutine
226 go func() {
227 err := startGRPCServer(grpcAddress, certFile, keyFile)
228 if err != nil {
229 log.Fatalf("failed to start gRPC server: %s", err)
230 }
231 }()
232
233 // fire the REST server in a goroutine
234 go func() {
235 err := startRESTServer(restAddress, grpcAddress, certFile)
236 if err != nil {
237 log.Fatalf("failed to start gRPC server: %s", err)
238 }
239 }()
240
241 // infinite loop
242 log.Printf("Entering infinite loop")
243 select {}
donNewtonAlphab3279ea2018-09-18 15:55:32 -0400244 //TODO publish periodic stats etc
Author Namea594e632018-08-10 11:33:58 -0400245 fmt.Println("AbstractOLT")
246}