OctopusDeploy/Halibut

Identifying a client

vincentparrett opened this issue · 5 comments

Migrating from wcf and hit an issue. In our wcf services, we used the ambient OperationContext.Current to get the calling address, however I cannot find a way to do this in halibut.

Any ideas on how to implement this? I've been looking at the code, and the required info is present in the listener ExecuteRequest method, but it's a major rabit hole to pass that down to the servicefactory (where it could be injected by a custom servicefactory).

So I tried creating a call context (with client address and thumbprint) and pushing that through everywhere... a nightmare due to all the funcs and the async nature of halibut and not really doable.

So I'm thinking about creating some sort of ambient callcontext, yes I know the ambient context pattern is seen as an anti-pattern these days but I can't really see any other way to do this. FWIW, I was just looking at .net core grpc and every service method receives a ServerCallContext object which has things like Host, Peer etc.

Is there any interest in this from the halibut team? It looks like a significant amount of work, so I don't want to start on this without some sort of buy in (ie I'm not looking to maintain a fork for this). The alternative is to switch away but I prefer halibut to grpc.

Can you expand on what you want the calling address for? Maybe there's another way of achieving your goal...

Something that might work, and is probably worth spiking out is to modify the ServiceInvoker to inspect the called method, and if there is a parameter of type HalibutCallContext (or something), then it passes it through. In theory, it shouldn't be a massive change?

We need the calling address because when our agents register with the server (by calling the agentregistrationservice.register method) we call back to the agents to verify we can connect and to get more details from it. At that point we need the client's thumbprint and hostname, so we can call them (the agents are in listening mode). At the moment there doesn't appear to be any way to identify the caller.

I did look at the serviceinvoker, but it doesn't have the information needed to make this possible. If you follow back from there, it's a long way up the call chain before you get to where that information is available and would require a lot method signature changes to pass it through, and you will hit roadblocks due to polling vs listening . I did also look at whether it could be added to the RequestMessage (which is passed to the serviceinvoker) but that is still a lot of work, you have to work back to the listener.ExecuteRequest methods to find the info needed.

My workaround right now is to send the hostname and thumbprint as parameters in the service call, extremely hacky.

At this point, our Tentacle registers with the Octopus Server via http, and then the Octopus Server initiates the connection back, so we dont have a need for this callback mechanism.

We're not against modifying to support the parameter sniffing approach (not a fan of the ambient call context approach), but as you mention, this might not be so simple.

If sending the hostname and thumbprint is working for your situation... I'd personally just look other way and ignore it :)

Whilst sending the hostname and thumbprint isn't ideal, it does work and it is happening over an ssl connection, so I guess unless someone steals a certificate it's reasonably secure. Moving on, nothing to see here ;)