public PluginServer(string listeningHost, int listeningPort, int appProtoVersion, ITLSConfig tlsConfig = null) { ListeningHost = listeningHost; ListeningPort = listeningPort; AppProtocolVersion = appProtoVersion; _server = new Server(); _health = new HealthServiceImpl(); _serverCreds = tlsConfig == null ? ServerCredentials.Insecure : TLSConfig.ToCredentials(tlsConfig); _serverPort = new ServerPort(ListeningHost, ListeningPort, _serverCreds); Server.Ports.Add(_serverPort); Server.Services.Add(Grpc.Health.V1.Health.BindService(_health)); // Based on: // https://github.com/hashicorp/go-plugin/blob/f444068e8f5a19853177f7aa0aea7e7d95b5b528/server.go#L257 // https://github.com/hashicorp/go-plugin/blob/f444068e8f5a19853177f7aa0aea7e7d95b5b528/server.go#L327 if (tlsConfig != null) { _ServerCertificate = Convert.ToBase64String(tlsConfig.ServerCertRaw); _HandshakeInfo = string.Join("|", CoreProtocolVersion, AppProtocolVersion, NetworkType, NetworkAddres, ConnectionProtocol, _ServerCertificate ); } else { _HandshakeInfo = string.Join("|", CoreProtocolVersion, AppProtocolVersion, NetworkType, NetworkAddres, ConnectionProtocol ); } }
/// <summary> /// Transforms the PKI components captured in this <c>TLSConfig</c> instance into a /// server credential object that can be used with a gRPC service endpoint (server port). /// </summary> public static SslServerCredentials ToCredentials(ITLSConfig tls, bool authenticateClient = false) { if (authenticateClient) { return(new SslServerCredentials( new List <KeyCertificatePair>() { new KeyCertificatePair(tls.ServerCert, tls.ServerKey) }, rootCertificates: tls.CaCert, forceClientAuth: false )); } else { return(new SslServerCredentials( new List <KeyCertificatePair>() { new KeyCertificatePair(tls.ServerCert, tls.ServerKey) } )); } }
public static async Task <PluginServer> RunService(Assembly pluginAssembly = null) { var tfRunId = Environment.GetEnvironmentVariable("TF_RUN_ID"); _log.LogInformation("###############################################################"); _log.LogInformation("TF Plugin Server Starting up..."); if (!string.IsNullOrEmpty(tfRunId)) { _log.LogInformation($"TF Run ID: {tfRunId}"); } // For debugging/troubleshooting: // _log.LogInformation("ENV: " + string.Join("\n", Environment.GetEnvironmentVariables() // .Cast<System.Collections.DictionaryEntry>() // .Select(x => $"{x.Key}={x.Value}"))); var magic = System.Environment.GetEnvironmentVariable(HandshakeMagicCookieName); if (HandshakeMagicCookieValue != magic) { throw new Exception("plugin should only be invoked by host"); } if (!int.TryParse(Environment.GetEnvironmentVariable(MinPortName), out var minPort)) { minPort = _listenPort; } if (!int.TryParse(Environment.GetEnvironmentVariable(MaxPortName), out var maxPort)) { maxPort = _listenPort + 100; } _listenPort = FindFreePort(minPort, maxPort); if (_listenPort <= 0) { throw new Exception("could not find a free listening port in the requested range"); } _tls = TLSConfigSimple.GenerateSelfSignedRSA(); _log.LogInformation("listen host: {@listenHost}", _listenHost); _log.LogInformation("listen ports: {@minPort}-{@maxPort} : {@listenPort}", minPort, maxPort, _listenPort); var server = new PluginServer(_listenHost, _listenPort, _appProtoVersion, _tls); var provider = new ProviderImpl(pluginAssembly); server.Services.Add(ProviderImpl.BindService(provider)); server.Health.SetStatus("plugin", HealthStatus.Serving); server.Start(); await server.WriteHandshakeAsync(); Console.WriteLine("Hit a key to exit..."); Console.ReadKey(); Console.WriteLine("...shutting down..."); _log.LogInformation("Shutting down..."); await server.ShutdownAsync(); _log.LogInformation("Stopped."); _log.LogInformation("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); return(server); }