how to exec a pod via WebSocket written in csharp - kubernetes

I want use a websocket client to exec commands in a Kubernetes pod,Develop a web terminal using xterm.js, i wrote websocket for the backend via asp.net core 3.1,
         websocket                          websocket
xterm.js -----------------> websocketServer ----------------> k8s
          cmd:ls                               cmd:ls
here is my websocketServer code:(asp.net core 3.1)
[HttpGet("/ws"), AllowAnonymous]
public async Task Terminal()
{
var config = KubernetesClientConfiguration.BuildConfigFromConfigFile(Environment.GetEnvironmentVariable("KUBECONFIG"));
var client = new Kubernetes(config);
var namespaces = client.ListNamespace();
if (!HttpContext.WebSockets.IsWebSocketRequest)
{
HttpContext.Response.StatusCode = 400;
}
//web websocketServer
using var websocketServer = await
HttpContext.WebSockets.AcceptWebSocketAsync();
await Echo(websocketServer);
//k8s websocket
var k8sWebSocket = await client.WebSocketNamespacedPodExecAsync(pod.Metadata.Name, "winter", "ls",pod.Spec.Containers[0].Name).ConfigureAwait(false);
//receive user input
async Task Echo(WebSocket webSocket)
{
var buffer = new byte[1024 * 4];
var result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
while (!result.CloseStatus.HasValue)
{
var serverMsg = Encoding.UTF8.GetBytes($"{Encoding.UTF8.GetString(buffer)}");
await webSocket.SendAsync(new ArraySegment<byte>(serverMsg, 0, serverMsg.Length), result.MessageType, result.EndOfMessage, CancellationToken.None);
//todo:
//how to transfer user input to k8sWebsocket...
//...
result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
//todo:
//how to transfer k8sWebsocket stdout to websocket...
//...
}
await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);
}
when run the project, execute the command as blow:
let webSocket = new WebSocket('ws://localhost:29126/ws');
an error occured: WebSocket connection to 'ws://localhost:29126/ws' failed:
and the error detail is Unable to read data from the transport connection: Software in your host aborted an established connection. .

Related

Call not working sometimes in sip_ua package of Dart

I'm Developing VOIP application in Flutter. Got below error and call not connected not in every case but in random case its happen.
Sip Registration Snippet
static void registeredSip(SipData sp) async {
UaSettings settings = UaSettings();
settings.webSocketUrl = 'wss://${sp.sipDomin}:${sp.sipPort}';
settings.webSocketSettings.allowBadCertificate = true;
var uri = 'sip:${sp.sipUsername}#${sp.sipDomin}';
settings.uri = uri;
settings.authorizationUser = sp.sipUsername;
settings.password = sp.sipPassword;
settings.displayName = sp.sipUsername;
globals.helper!.start(settings);
}
Starting Sip Call snippets below
SIPUAHelper helperObj = globals.helper!;
helperObj.call(typedNumber,voiceonly: true, mediaStream: null);
Error
sip_ua_helper.dart:224 ::: call failed with cause: Code: [408], Cause: Canceled, Reason: SIP ;cause=408 ;text="Request Timeout"
I'm using Sip_ua for Calling.

Dart client Socket connecting but not sending data to server?

I have a server running on a Raspberry Pi which is accessible from a browser.
http://192.168.1.67:55XXX/?email=a#b.com
yields:-
{Order=[{no=0, day_0=1, price=0, name=PPAC SUPERTHERM 20K, display_colour=blue, notice=1, special_order=false}, {no=1, day_0=1, price=0, name=SLACK 50KG , display_colour=blue, notice=1, special_order=false}, {no=0, day_0=1, price=0, name=PPAC SUPERTHERM 20K, display_colour=blue, day_5=1, notice=1, special_order=false, day_3=1}, {no=1, day_0=1, price=0, name=SLACK 50KG , display_colour=blue, day_5=1, notice=1, special_order=false, day_3=1}], Details={address=xx Farriers Lea, phone=0xxxx 606635, name=Fred Bloggs, mobile=, details=end shed on drive, email=a#b.com}}
I am using VSCODE to debug dart code.
my dart code:-
String remote_ip = '192.168.1.67'; //212.159.118.177';
var remote_port = 55XXX;
Socket socket;
String _dataToBeSent = "http://?email=a#b.com\n";
var reply;
// connect
main(List<String> arguments) async {
await _remoteServerConnect();
}
// REMOTE SERVER CONNECT
Future _remoteServerConnect() async {
// await Socket.connect(remote_ip, remote_port).then((Socket sock){
await Socket.connect(remote_ip, remote_port).then((Socket sock) {
socket = sock;
print('Got connected ${socket.remoteAddress}');
socket.listen(dataHandler,
onError: errorHandler, onDone: doneHandler, cancelOnError: false);
}).catchError((AsyncError e) {
print("Unable to connect: $e");
exit(1);
});
}
void dataHandler(data) async {
await print('"'+String.fromCharCodes(data).trim()+'"');
if (String.fromCharCodes(data).trim().endsWith('html')) {
print("Send Data = $_dataToBeSent");
socket.add(utf8.encode(_dataToBeSent));
// socket.writeln(_dataToBeSent);
socket.flush();
await Future.delayed(Duration(seconds: 5));
}
}
void errorHandler(error, StackTrace trace) {
print(error);
}
void doneHandler() {
// socket.destroy();
exit(0);
}
The dart debug consol yields:-
Connecting to VM Service at ws://127.0.0.1:54799/kE9Xa1JQclk=/ws
Got connected InternetAddress('192.168.1.67', IPv4)
"HTTP/1.1 200 OK" <sent by server
"ContentType: text/html" <sent by server
Send Data = http://?email=a#b.com
Exited
The server consol yields:-
Server is ready
WEB Client connected: /192.168.1.66
05.08/10:34:21.17 - Waiting for command..
05.08/10:34:31.80 - Socket Timeout
05.08/10:34:31.82 - Done -------------
05.08/10:34:31.82 - Waiting for command..
Connection has been closed
Server is ready
It would seem the
socket.add(utf8.encode(_dataToBeSent));
// socket.writeln(_dataToBeSent);
socket.flush();
did not send data to the server?? Why?? any ideas gratefully received!
Disabling my dev machines firewall did NOT improve answer!
Steve
The server used
final DataInputStream in = new DataInputStream(clientSocket.getInputStream());
while (estimatedTime < 60000) {
report("Waiting for command..");
try {
// in.readNBytes(command.data, 0, command.length);
in.readFully(command.data);
to receive the data command.data is 100bytes long so was waiting for the complete input. I padded to 100 bytes worked fine - will sort a better solution later.

Cannot connect to to FastAPI with WebSocket in Flutter. 403 forbidden / code 1006

So I've been trying for while to establish a websocket connection between my flutter app and FastAPI.
I believe the problem lies in Flutter.
So far i've tried the flutter packages socket_io_client, web_socket_channel and websocket_manager to no awail.
I suspect it might have to do with the app architecture maybe... bit at a loss atm.
Here is the flutter errors:
I/onListen(26110): arguments: null
I/EventStreamHandler(26110): 🔴 event sink
I/onListen(26110): arguments: null
I/EventStreamHandler(26110): 🔴 event sink
W/System.err(26110): java.net.ProtocolException: Expected HTTP 101 response but was '403 Forbidden'
W/System.err(26110): at okhttp3.internal.ws.RealWebSocket.checkUpgradeSuccess$okhttp(RealWebSocket.kt:185)
W/System.err(26110): at okhttp3.internal.ws.RealWebSocket$connect$1.onResponse(RealWebSocket.kt:156)
W/System.err(26110): at okhttp3.RealCall$AsyncCall.run(RealCall.kt:140)
W/System.err(26110): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
W/System.err(26110): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
W/System.err(26110): at java.lang.Thread.run(Thread.java:923)
I/EventStreamHandler(26110): ✅ sink is not null
I/flutter (26110): websocket closed
Im aware it says the 403 forbidden came from my API, though i know websocket connection is possible, as i've tested it with javascript.
here is the log from the API:
DEBUG | websockets.protocol:__init__:244 - server - state = CONNECTING
DEBUG | websockets.protocol:connection_made:1340 - server - event = connection_made(<_SelectorSocketTransport fd=484 read=polling write=<idle, bufsize=0>>)
DEBUG | websockets.protocol:data_received:1412 - server - event = data_received(<422 bytes>)
DEBUG | websockets.server:read_http_request:237 - server < GET /11 HTTP/1.1
DEBUG | websockets.server:read_http_request:238 - server < Headers([('authorization', 'Bearer *JWTTOKEN*'), ('upgrade', 'websocket'), ('connection', 'Upgrade'), ('sec-websocket-key', 'zytoCsWVlcmsKghL5XFEdA=='), ('sec-websocket-version', '13'), ('host', '10.0.2.2:8000'), ('accept-encoding', 'gzip'), ('user-agent', 'okhttp/4.3.1')])
INFO | uvicorn.protocols.websockets.websockets_impl:asgi_send:198 - ('127.0.0.1', 50772) - "WebSocket /11" 403
DEBUG | websockets.server:write_http_response:256 - server > HTTP/1.1 403 Forbidden
DEBUG | websockets.server:write_http_response:257 - server > Headers([('Date', 'Fri, 09 Apr 2021 11:10:11 GMT'), ('Server', 'Python/3.7 websockets/8.1'), ('Content-Length', '0'), ('Content-Type', 'text/plain'), ('Connection', 'close')])
DEBUG | websockets.server:write_http_response:267 - server > body (0 bytes)
DEBUG | websockets.protocol:fail_connection:1261 - server ! failing CONNECTING WebSocket connection with code 1006
DEBUG | websockets.protocol:connection_lost:1354 - server - event = connection_lost(None)
DEBUG | websockets.protocol:connection_lost:1356 - server - state = CLOSED
DEBUG | websockets.protocol:connection_lost:1365 - server x code = 1006, reason = [no reason]
I have all the WebSocket code in a Class that is beeing 'provided', I.E WebSocketState:
return runApp(
MultiProvider(
providers: [
Provider<AuthenticationState>(
create: (_) => new AuthenticationState(),
),
Provider<WebSocketState>(
create: (_) => new WebSocketState(),
),
],
child: MyApp(),
),
);
WebSocketState:
class WebSocketState {
final _socketMessage = StreamController<Message>();
Sink<Message> get getMessageSink => _socketMessage.sink;
Stream<Message> get getMessageStream => _socketMessage.stream;
WebsocketManager socket;
bool isConnected() => true;
void connectAndListen(int userId) async {
var token = await secureStorage.read(key: 'token');
socket = WebsocketManager(
'ws://10.0.2.2:8000/$userId', {'Authorization': 'Bearer $token'});
socket.onClose((dynamic message) {
print('websocket closed');
});
// Listen to server messages
socket.onMessage((dynamic message) {
print("Message = " + message.toString());
});
// Connect to server
socket.connect();
}
void dispose() {
_socketMessage.close();
socket.close();
}
}
the connectAndListen method is called in the first/main page after user has authenticated, then in other Pages the websocket is beeing used.
#override
void didChangeDependencies() {
super.didChangeDependencies();
Provider.of<WebSocketState>(context, listen: false).connectAndListen(
Provider.of<AuthenticationState>(context, listen: false).id);
}
API websocket 'class':
websocket_notifier.py
from enum import Enum
import json
from typing import List
class SocketClient:
def __init__(self, user_id: int, websocket: WebSocket):
self.user_id = user_id
self.websocket = websocket
class WSObjects(Enum):
Message = 0
class Notifier:
def __init__(self):
self.connections: List[SocketClient] = []
self.generator = self.get_notification_generator()
async def get_notification_generator(self):
while True:
message = yield
await self._notify(message)
async def push(self, msg: str):
await self.generator.asend(msg)
async def connect(self, user_id: int, websocket: WebSocket):
await websocket.accept()
self.connections.append(SocketClient(user_id, websocket))
def remove(self, websocket: WebSocket):
client: SocketClient
for x in self.connections:
if x.websocket == websocket:
client = x
self.connections.remove(client)
async def _notify(self, message: str):
living_connections = []
while len(self.connections) > 0:
# Looping like this is necessary in case a disconnection is handled
# during await websocket.send_text(message)
client = self.connections.pop()
await client.websocket.send_text(message)
living_connections.append(client)
self.connections = living_connections
async def send(self, user_id: int, info: WSObjects, json_object: dict):
print("WS send running")
msg = {
"info": info,
"data": json_object
}
print("connections count: " + str(len(self.connections)))
for client in self.connections:
if client.user_id == user_id:
print("WS sending msg to ${client.user_id}")
await client.websocket.send_text(json.dumps(msg))
break
notifier = Notifier()
API main:
from fastapi import FastAPI
from websocket_notifier import notifier
from starlette.websockets import WebSocket, WebSocketDisconnect
app = FastAPI()
#app.get("/")
async def root():
return {"message": "Root"}
#app.websocket("/ws/{user_id}")
async def websocket_endpoint(user_id: int, websocket: WebSocket):
await notifier.connect(user_id, websocket)
try:
while True:
data = await websocket.receive_text()
await websocket.send_text(f"Message text was: {data}")
except WebSocketDisconnect:
notifier.remove(websocket)
#app.on_event("startup")
async def startup():
# Prime the push notification generator
await notifier.generator.asend(None)
Any ideas what Im doing wrong? (the other flutter websocket packages I've used virutally In the same way as the one I showed)
through lots of testing i finally found a way to get websockets to work with my flutter app and fastapi.
https://github.com/tiangolo/fastapi/issues/129
Had to try a bit of different things from that issue thread. But endend up with using python-socketio. I had to use a lower version of python-socketio to be compatible with the newest flutter socket_io_client package.
For those who have the same problem, please also check #2639. Prefix of the APIRouter does not work in websocket decorator.

How to start an UiPath Process from Salesforce interface

How I can Start an UiPath Process on UiPath Robot from the Salesforce interface?
I know that Salesforce can send REST API commands to other software.
I tried to do exactly the same thing, like you in your movie on YouTube.
Please, can you look on my/Your apex code bellow, and maybe help me. Thanks!!
{
//#future(callout=true)
public static void startProcess(String param1,String param2)
{
Http http = new Http();
HttpRequest rm = new HttpRequest();
rm.setEndpoint('https://account.uipath.com/oauth/token');
rm.setMethod('POST');
rm.setHeader('Content-Type', 'application/json');
rm.setHeader('X-UIPATH-TenantName', 'ioDefault');
//rm.setTimeout(60000);
JSONGenerator gen = JSON.createGenerator(true);
gen.writeStartObject();
gen.writeStringField('grant_type','refresh_token');
gen.writeStringField('client_id','8DEv1AMNXczW3y4U15LL3jYf62jK93n5');
gen.writeStringField('refresh_token','2I7ZERqOZHFmzVzyPUE_sdf-l-dGa4086xN8fyrW-xF8-');
gen.writeEndObject();
rm.setBody(gen.getAsString());
HttpResponse rs = http.send(rm);
System.debug(rs.getBody());
Map<String,Object> res = (Map<String,Object>)JSON.deserializeUntyped(rs.getBody());
System.debug(String.valueOf(res.get('access_token')));
HttpRequest rm2 = new HttpRequest();
rm2.setMethod('POST');
rm2.setEndpoint('https://platform.uipath.com/zuhtkqf/ioDefault/odata/Jobs/UiPath.Server.Configuration.OData.StartJobs');
rm2.setHeader('Content-Type', 'application/json');
rm2.setHeader('X-UIPATH-TenantName', 'ioDefault');
rm2.setHeader('Authorization', 'Bearer '+String.valueOf(res.get('access_token')));
//rm2.setTimeout(60000);
JSONGenerator gen2 = JSON.createGenerator(true);
/// start a simple process without parameters
gen2.writeStartObject();
gen2.writeFieldName('startInfo');
gen2.writeStartObject();
gen2.writeStringField('ReleaseKey','6aa09f52-ef47-47aa-ab2e-8e487e7841e5');
gen2.writeStringField('Strategy','All');
gen2.writeEndObject();
gen2.writeEndObject();
/// start a simple process with parameters
/* gen2.writeStartObject();
gen2.writeFieldName('startInfo');
gen2.writeStartObject();
gen2.writeStringField('ReleaseKey','YOUR release KEY for process see the YouTube movie below');
gen2.writeStringField('Strategy','All');
gen2.writeStringField('InputArguments','{\"param1\":\"'+param1+'\",\"param2\":\"'+param2+'\"}');
gen2.writeEndObject();
gen2.writeEndObject();
*/
rm2.setBody(gen2.getAsString());
HttpResponse rs2 = http.send(rm2);
System.debug(rs2.getBody());
}
}

Calling External WCF Service (using generated client) from CRM sandboxed plugin OnPremise is failing

How to call HTTPS WCF web service in Plugin, plugin assembly is registered in sandbox mode. I am getting System.Security.SecurityException exception, Can somebody please provide the way to all https web service. My code is below :
BasicHttpBinding myBinding = new BasicHttpBinding();
myBinding.MaxReceivedMessageSize = Int32.MaxValue;
myBinding.Name = “basicHttpBinding”;
if (EndPoint.ToLower().Contains(“https://”))
{
//Throwing exception here – System.Security.SecurityException exception,
ServicePointManager.ServerCertificateValidationCallback += (sendr, cert, chain, sslPolicyErrors) => true;
ServicePointManager.SecurityProtocol = (SecurityProtocolType)768 | (SecurityProtocolType)3072 | (SecurityProtocolType)192;
myBinding.Security.Mode = BasicHttpSecurityMode.Transport;
}
else
{
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
myBinding.Security.Mode = BasicHttpSecurityMode.None;
}
myBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
myBinding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;
myBinding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName;
EndpointAddress endPointAddress = new EndpointAddress(EndPoint);
WebIALClient myClient = new WebIALClient(myBinding, endPointAddress)
Since you are in on-premise version, you can register the plugin assembly in non-sandbox mode. ie Isolation mode = none to overcome such errors.
In case you wanted to use sandbox mode, try using WebClient class for invoking WCF service call. Read more
using (WebClient client = new WebClient())
{
byte[] responseBytes = client.DownloadData(webAddress);
string response = Encoding.UTF8.GetString(responseBytes);
tracingService.Trace(response);
// For demonstration purposes, throw an exception so that the response
// is shown in the trace dialog of the Microsoft Dynamics CRM user interface.
throw new InvalidPluginExecutionException("WebClientPlugin completed successfully.");
}
Can you try and also include: using System.Web.Http.Cors;
[EnableCors(origins: "*", headers: "*", methods: "*")]
[Route("api/ConvertUpload/{env}/{id}")]
public string Get(string env, string id)
{
return "hi";
}
You may have to use WebClient as #Arun has mentioned.