blob: 19acd720e7156a46c28f31b59669b74d3dcf6b0a [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
40const (
41 clientIDKey contextKey = iota
42)
43
44/*
45GetLogger - returns the logger
46*/
47func credMatcher(headerName string) (mdName string, ok bool) {
48 if headerName == "Login" || headerName == "Password" {
49 return headerName, true
50 }
51 return "", false
52}
53
54// authenticateAgent check the client credentials
55func authenticateClient(ctx context.Context, s *api.Server) (string, error) {
56 if md, ok := metadata.FromIncomingContext(ctx); ok {
57 clientLogin := strings.Join(md["login"], "")
58 clientPassword := strings.Join(md["password"], "")
59
60 if clientLogin != "john" {
61 return "", fmt.Errorf("unknown user %s", clientLogin)
62 }
63 if clientPassword != "doe" {
64 return "", fmt.Errorf("bad password %s", clientPassword)
65 }
66
67 log.Printf("authenticated client: %s", clientLogin)
68 return "42", nil
69 }
70 return "", fmt.Errorf("missing credentials")
71}
72
73// unaryInterceptor call authenticateClient with current context
74func unaryInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
75 s, ok := info.Server.(*api.Server)
76 if !ok {
77 return nil, fmt.Errorf("unable to cast server")
78 }
79 clientID, err := authenticateClient(ctx, s)
80 if err != nil {
81 return nil, err
82 }
83
84 ctx = context.WithValue(ctx, clientIDKey, clientID)
85 return handler(ctx, req)
86}
87
88func startGRPCServer(address, certFile, keyFile string) error {
89 // create a listener on TCP port
90 lis, err := net.Listen("tcp", address)
91 if err != nil {
92 return fmt.Errorf("failed to listen: %v", err)
93 }
94
95 // create a server instance
96 s := api.Server{}
97
98 // Create the TLS credentials
99 creds, err := credentials.NewServerTLSFromFile(certFile, keyFile)
100 if err != nil {
101 return fmt.Errorf("could not load TLS keys: %s", err)
102 }
103
104 // Create an array of gRPC options with the credentials
105 opts := []grpc.ServerOption{grpc.Creds(creds),
106 grpc.UnaryInterceptor(unaryInterceptor)}
107
108 // create a gRPC server object
109 grpcServer := grpc.NewServer(opts...)
110
111 // attach the Ping service to the server
112 api.RegisterAddChassisServer(grpcServer, &s)
113 api.RegisterAddOLTChassisServer(grpcServer, &s)
114
115 // start the server
116 log.Printf("starting HTTP/2 gRPC server on %s", address)
117 if err := grpcServer.Serve(lis); err != nil {
118 return fmt.Errorf("failed to serve: %s", err)
119 }
120
121 return nil
122}
123func startRESTServer(address, grpcAddress, certFile string) error {
124 ctx := context.Background()
125 ctx, cancel := context.WithCancel(ctx)
126 defer cancel()
127
128 mux := runtime.NewServeMux(runtime.WithIncomingHeaderMatcher(credMatcher))
129 creds, err := credentials.NewClientTLSFromFile(certFile, "")
130 if err != nil {
131 return fmt.Errorf("could not load TLS certificate: %s", err)
132 }
133
134 // Setup the client gRPC options
135 opts := []grpc.DialOption{grpc.WithTransportCredentials(creds)}
136 err = api.RegisterAddChassisHandlerFromEndpoint(ctx, mux, grpcAddress, opts)
137 _ = api.RegisterAddOLTChassisHandlerFromEndpoint(ctx, mux, grpcAddress, opts)
138 if err != nil {
139 return fmt.Errorf("could not register service Ping: %s", err)
140 }
141
142 log.Printf("starting HTTP/1.1 REST server on %s", address)
143 http.ListenAndServe(address, mux)
144
145 return nil
146}
147func main() {
148 debugPtr := flag.Bool("d", false, "Log Level Debug")
149 flag.Parse()
150 settings.SetDebug(*debugPtr)
151
152 file, err := os.OpenFile("AbstractOLT.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
153 if err != nil {
154 log.Fatalln("Failed to open log file", file, ":", err)
155 }
156 log.SetOutput(file)
157 log.SetFlags(log.Ldate | log.Ltime | log.Lmicroseconds | log.Lshortfile)
158 log.Printf("Setting Debug to %t\n", settings.GetDebug())
159
160 grpcAddress := fmt.Sprintf("%s:%d", "AbstractOLT.dev.atl.foundry.att.com", 7777)
161 restAddress := fmt.Sprintf("%s:%d", "AbstractOLT.dev.atl.foundry.att.com", 7778)
162 certFile := "cert/server.crt"
163 keyFile := "cert/server.key"
164
165 // fire the gRPC server in a goroutine
166 go func() {
167 err := startGRPCServer(grpcAddress, certFile, keyFile)
168 if err != nil {
169 log.Fatalf("failed to start gRPC server: %s", err)
170 }
171 }()
172
173 // fire the REST server in a goroutine
174 go func() {
175 err := startRESTServer(restAddress, grpcAddress, certFile)
176 if err != nil {
177 log.Fatalf("failed to start gRPC server: %s", err)
178 }
179 }()
180
181 // infinite loop
182 log.Printf("Entering infinite loop")
183 select {}
184 fmt.Println("AbstractOLT")
185}