Add python CommandExecutor gRPC server w/ auth 24/85124/6
authorAlexis de Talhouët <adetalhouet89@gmail.com>
Fri, 12 Apr 2019 22:51:26 +0000 (18:51 -0400)
committerAlexis de Talhouët <adetalhouet89@gmail.com>
Tue, 16 Apr 2019 14:38:51 +0000 (10:38 -0400)
Change-Id: Ie5fefb804c3d88c5be19d19da10d4d2b5f36008c
Issue-ID: CCSDK-1164
Signed-off-by: Alexis de Talhouët <adetalhouet89@gmail.com>
ms/command-executor/pom.xml
ms/command-executor/src/main/python/command_executor_server.py [new file with mode: 0644]
ms/command-executor/src/main/python/request_header_validator_interceptor.py [new file with mode: 0644]

index 903ccdc..af1b4f4 100755 (executable)
                     </execution>
                 </executions>
             </plugin>
-            <!--<plugin>-->
-                <!--<artifactId>maven-assembly-plugin</artifactId>-->
-                <!--<version>3.1.0</version>-->
-                <!--<configuration>-->
-                    <!--<outputDirectory>${basedir}/target/docker-stage</outputDirectory>-->
-                    <!--<descriptors>-->
-                        <!--<descriptor>src/main/docker/distribution.xml</descriptor>-->
-                    <!--</descriptors>-->
-                    <!--<tarLongFileMode>posix</tarLongFileMode>-->
-                <!--</configuration>-->
-                <!--<executions>-->
-                    <!--<execution>-->
-                        <!--<id>${assembly.id}</id>-->
-                        <!--<phase>package</phase>-->
-                        <!--<goals>-->
-                            <!--<goal>single</goal>-->
-                        <!--</goals>-->
-                    <!--</execution>-->
-                <!--</executions>-->
-            <!--</plugin>-->
+            <plugin>
+                <artifactId>maven-assembly-plugin</artifactId>
+                <version>3.1.0</version>
+                <configuration>
+                    <outputDirectory>${basedir}/target/docker-stage</outputDirectory>
+                    <descriptors>
+                        <descriptor>src/main/docker/distribution.xml</descriptor>
+                    </descriptors>
+                    <tarLongFileMode>posix</tarLongFileMode>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>${assembly.id}</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>single</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
             <plugin>
                 <groupId>org.codehaus.groovy.maven</groupId>
                 <artifactId>gmaven-plugin</artifactId>
diff --git a/ms/command-executor/src/main/python/command_executor_server.py b/ms/command-executor/src/main/python/command_executor_server.py
new file mode 100644 (file)
index 0000000..35eed8e
--- /dev/null
@@ -0,0 +1,69 @@
+#!/usr/bin/python
+
+#
+# Copyright (C) 2019 Bell Canada.
+#
+# 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.
+#
+from builtins import KeyboardInterrupt
+from concurrent import futures
+import time
+import sys
+
+import grpc
+
+import proto.CommandExecutor_pb2_grpc as CommandExecutor_pb2_grpc
+
+from request_header_validator_interceptor import RequestHeaderValidatorInterceptor
+
+_ONE_DAY_IN_SECONDS = 60 * 60 * 24
+
+
+class CommandExecutorServer(CommandExecutor_pb2_grpc.CommandExecutorServiceServicer):
+
+    def prepareEnv(self, request, context):
+        return
+
+    def executeCommand(self, request, context):
+        return
+
+
+def serve():
+    port = sys.argv[1]
+    basic_auth = sys.argv[2] + ' ' + sys.argv[3]
+
+    header_validator = RequestHeaderValidatorInterceptor(
+        'authorization', basic_auth, grpc.StatusCode.UNAUTHENTICATED,
+        'Access denied!')
+
+    server = grpc.server(
+        futures.ThreadPoolExecutor(max_workers=10),
+        interceptors=(header_validator,))
+
+    CommandExecutor_pb2_grpc.add_CommandExecutorServiceServicer_to_server(
+        CommandExecutorServer(), server)
+
+    server.add_insecure_port('[::]:' + port)
+    server.start()
+
+    print("Command Executor Server started on %s" % port)
+
+    try:
+        while True:
+            time.sleep(_ONE_DAY_IN_SECONDS)
+    except KeyboardInterrupt:
+        server.stop(0)
+
+
+if __name__ == '__main__':
+    serve()
diff --git a/ms/command-executor/src/main/python/request_header_validator_interceptor.py b/ms/command-executor/src/main/python/request_header_validator_interceptor.py
new file mode 100644 (file)
index 0000000..2613573
--- /dev/null
@@ -0,0 +1,38 @@
+#
+# Copyright (C) 2019 Bell Canada.
+#
+# 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.
+#
+
+import grpc
+
+
+def _unary_unary_rpc_terminator(code, details):
+    def terminate(ignored_request, context):
+        context.abort(code, details)
+
+    return grpc.unary_unary_rpc_method_handler(terminate)
+
+
+class RequestHeaderValidatorInterceptor(grpc.ServerInterceptor):
+
+    def __init__(self, header, value, code, details):
+        self._header = header
+        self._value = value
+        self._terminator = _unary_unary_rpc_terminator(code, details)
+
+    def intercept_service(self, continuation, handler_call_details):
+        if (self._header, self._value) in handler_call_details.invocation_metadata:
+            return continuation(handler_call_details)
+        else:
+            return self._terminator