Convert to cniservice
authorMichael Cambria <mcambria@redhat.com>
Tue, 16 Apr 2019 18:22:12 +0000 (14:22 -0400)
committerMichael Cambria <mcambria@redhat.com>
Tue, 16 Apr 2019 18:22:12 +0000 (14:22 -0400)
Makefile
api/api.proto
api/handler.go
client/main.go
server/main.go

index 8ab9d00..1532458 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,7 @@ CLIENT_OUT := "bin/client"
 API_OUT := "api/api.pb.go"
 API_REST_OUT := "api/api.pb.gw.go"
 API_SWAG_OUT := "api/api.swagger.json"
-PKG := "gitlab.com/pantomath-io/demo-grpc"
+PKG := "github.com/mccv1r0/demo-grpc"
 SERVER_PKG_BUILD := "${PKG}/server"
 CLIENT_PKG_BUILD := "${PKG}/client"
 PKG_LIST := $(shell go list ${PKG}/... | grep -v /vendor/)
index 2c6c20d..81596ca 100644 (file)
@@ -14,4 +14,38 @@ service Ping {
         body: "*"
     };
   }
-}
\ No newline at end of file
+}
+
+
+service CNIserver {
+  // Process CNI message
+  rpc CNIop (CNImsg) returns (CNIresult) {}
+}
+
+enum CmdType {
+  VERSION = 0;
+  ADD = 1;
+  CHECK = 2;
+  DEL = 3;
+}
+
+message CNIargs {
+  string name = 1;
+  string value = 2;
+}
+
+message CNImsg {
+  CmdType cmd = 1;
+  string containerID = 2;
+  string netNS = 3;
+  string ifName = 4;
+  repeated CNIargs args = 5;
+  string stdIn = 6;
+}
+
+message CNIresult {
+  CmdType cmd = 1;
+  string error = 2;
+  string stdOut = 3;
+}
+
index f123180..5026e61 100644 (file)
@@ -15,3 +15,26 @@ func (s *Server) SayHello(ctx context.Context, in *PingMessage) (*PingMessage, e
        log.Printf("Receive message %s", in.Greeting)
        return &PingMessage{Greeting: "bar"}, nil
 }
+
+// Server represents the gRPC server
+type CNIServer struct {
+}
+
+// CNIop generates result to a CNImsg
+func (s *CNIServer) CNIop(ctx context.Context, in *CNImsg) (*CNIresult, error) {
+       log.Printf("Receive message Cmd: %s", in.Cmd)
+       log.Printf("Receive message ContainerID: %s", in.ContainerID)
+       log.Printf("Receive message NetNS: %s", in.NetNS)
+       log.Printf("Receive message IfName: %s", in.IfName)
+       log.Printf("Receive message StdIn: %s", in.StdIn)
+
+       cniResult := CNIresult{
+              Cmd: in.Cmd,
+              StdOut: "stdOutStringHere",
+       }
+
+       log.Printf("Response from server: %s", cniResult.StdOut)
+       return &cniResult, nil
+}
+
+
index d571fef..d28af2d 100644 (file)
@@ -3,7 +3,7 @@ package main
 import (
        "log"
 
-       "gitlab.com/pantomath-io/demo-grpc/api"
+       "github.com/mccv1r0/demo-grpc/api"
        "golang.org/x/net/context"
        "google.golang.org/grpc"
        "google.golang.org/grpc/credentials"
@@ -50,6 +50,7 @@ func main() {
        }
        defer conn.Close()
 
+/*
        c := api.NewPingClient(conn)
 
        response, err := c.SayHello(context.Background(), &api.PingMessage{Greeting: "foo"})
@@ -57,4 +58,21 @@ func main() {
                log.Fatalf("error when calling SayHello: %s", err)
        }
        log.Printf("Response from server: %s", response.Greeting)
+*/
+
+       // CNI Test 
+       cni := api.NewCNIserverClient(conn)
+
+       cniMsg := api.CNImsg{
+              Cmd: api.CmdType_ADD,
+              ContainerID: "containerOne",
+              NetNS: "mcc-test-0",
+              IfName: "ensX",
+              StdIn: "stdInStringHere",
+       }
+       result, err := cni.CNIop(context.Background(), &cniMsg)
+       if err != nil {
+               log.Fatalf("error when calling CNIop: %s", err)
+       }
+       log.Printf("Response from server: %s", result.StdOut)
 }
index e879387..162b303 100644 (file)
@@ -11,7 +11,7 @@ import (
 
        "golang.org/x/net/context"
 
-       "gitlab.com/pantomath-io/demo-grpc/api"
+       "github.com/mccv1r0/demo-grpc/api"
        "google.golang.org/grpc"
        "google.golang.org/grpc/credentials"
        "google.golang.org/grpc/metadata"
@@ -31,6 +31,7 @@ func credMatcher(headerName string) (mdName string, ok bool) {
        return "", false
 }
 
+/*
 // authenticateAgent check the client credentials
 func authenticateClient(ctx context.Context, s *api.Server) (string, error) {
        if md, ok := metadata.FromIncomingContext(ctx); ok {
@@ -66,6 +67,43 @@ func unaryInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServ
 
        return handler(ctx, req)
 }
+*/
+
+// authenticateAgent check the client credentials
+func authenticateClient(ctx context.Context, s *api.CNIServer) (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")
+}
+
+// unaryInterceptorCNI 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.CNIServer)
+       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
@@ -74,6 +112,7 @@ func startGRPCServer(address, certFile, keyFile string) error {
                return fmt.Errorf("failed to listen: %v", err)
        }
 
+/*
        // create a server instance
        s := api.Server{}
 
@@ -92,12 +131,39 @@ func startGRPCServer(address, certFile, keyFile string) error {
 
        // attach the Ping service to the server
        api.RegisterPingServer(grpcServer, &s)
-
-       // start the server
+*/
+/*
+       // Original
        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)
        }
+*/
+
+       // create a CNI server instance
+       cni := api.CNIServer{}
+
+       // 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
+       grpcCNIServer := grpc.NewServer(opts...)
+
+       // attach the CNI service to the server
+       api.RegisterCNIserverServer(grpcCNIServer, &cni)
+
+       // start the server
+       log.Printf("starting CNI HTTP/2 gRPC server on %s", address)
+       if err := grpcCNIServer.Serve(lis); err != nil {
+               return fmt.Errorf("failed to serve: %s", err)
+       }
 
        return nil
 }