How to call Cloud Run from out side of Cloud Run/GCP? - google-cloud-run

I have a simple Spring Boot service 'say-hi' to take GET request under /say-hi and return 'hello'. It's deployed in managed Cloud Run. Suppose I don't want to open it to the general public. Now I wanted to do two things:
1. allow developer (I myself) to access 'say-hi'
2. allow another Spring Boot service outside of Cloud Run be able to make the call to 'say-hi'
For my goal 1:
Weird thing is that curl command doesn't work, but Insomnia works fine. Basically, I followed the doc, I added my google account to roles/run.invoker, but the curl command says Network is unrechable:
curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" http://say-hi-0-1-0-q6g2cgbzna-ew.a.run.app:8080/say-hi -v
Errors:
* Trying 216.239.36.53...
* Trying 2001:4860:4802:36::35...
* Immediate connect fail for 2001:4860:4802:36::35: Network is unreachable
* Trying 2001:4860:4802:36::35...
* Immediate connect fail for 2001:4860:4802:36::35: Network is unreachable
* Trying 2001:4860:4802:36::35...
* Immediate connect fail for 2001:4860:4802:36::35: Network is unreachable
However, if I run gcloud auth print-identity-token separately to get the token first and then sent the GET request from Insomnia client, it works... I'm wondering why...
For my goal 2
I assume the right session to look at it here. Does this mean if I wanted to access 'say-hi' from outside of Cloud Run manged (both from my own laptop and from other GKE instances), I need to have IAP enable for my project? if yes, how to integrate cloud run with IAP?

After a long day of searching and reading. Finally get a working version. The given doc of service-to-service authentication given by Google Cloud Run was really misleading me towards IAP, and the code here left a few places unclarified. Turned out to call Cloud Run service, I didn't need IAP at all. Big thanks to this blog where I grabbed the solution from.
#PostMapping(value="/call-say-hi")
public ResponseEntity<String> callSayHi() throws URISyntaxException, IOException {
ServiceAccountCredentials serviceAccountCredentials =
ServiceAccountCredentials.fromStream(new FileInputStream(SERVICE_ACCOUNT_JSON_KEY_PATH));
serviceAccountCredentials.createScoped(IAM_SCOPE);
IdTokenCredentials idTokenCredentials = IdTokenCredentials.newBuilder()
.setIdTokenProvider(serviceAccountCredentials)
.setTargetAudience(TARGET_AUDIENCE)
.build();
GenericUrl genericUrl = new GenericUrl(TARGET_AUDIENCE+"/say-hi");
HttpCredentialsAdapter adapter = new HttpCredentialsAdapter(idTokenCredentials);
HttpRequest request = httpTransport.createRequestFactory(adapter).buildGetRequest(genericUrl);
request.setThrowExceptionOnExecuteError(false);
HttpResponse response = request.execute();
String r = response.parseAsString();
System.out.println(r);
return ResponseEntity.status(HttpStatus.OK).body(r);
}
Where the TARGET_AUDIENCE is the deployed Cloud Run service URL

Related

How to verify requests from Wiremock deployed to a remote host based on it's URL only?

I've implemented a custom Wiremock Server programmatically using Spring Boot and this service is deployed and running on a remote host.
The only way to access this Wiremock Server is URL provided by DevOps. Let's say testWiremockHost.com
All mappings are working fine and Wiremock responds properly.
But I do have couple of questions:
1) There's no response from the Server when I try GET request on testWiremockHost.com/__admin
2) My goal is to verify requests that were sent to this Wiremock after another service is triggered, so I also need to find a way to properly define instance of this remote Wiremock in my tests in order to track incoming requests. Previously, when I tried to verify the requests from 'localhost' Wiremock server everything was just fine, but unfortunately I can't do the same for the remote one.
The latest code I've tried is the following:
wiremock = new WireMockBuilder().host("testWiremockHost.com").https().build();
*send request*
wiremock.verify(1, postRequestedFor(urlEqualTo("/testEnpoint")))
I get the following error as a result:
"detail" : "Unrecognized field \"timestamp\" (class com.github.tomakehurst.wiremock.common.Errors), not marked as ignorable"
I'd appreciate any help on this, thanks in advance!

Google Cloud BigTable - slow response time from outside of Google Project

When all the code is running in a Google Project; performance is as expected.
However; during development, I connect my laptop to a test Google Project BigTable instance; and each query takes 2-4 seconds to run.
Its a similar response response when I trigger commands using cbt CLI commands.
Is there a known reason for this overhead? Perhaps its how auth needs to be done for external connections?
On start up I see the below logs:
Opening connection for projectId ..., instanceId ..., on data host bigtable.googleapis.com, admin host bigtableadmin.googleapis.com.
Bigtable options: BigtableOptions{dataHost=bigtable.googleapis.com, adminHost=bigtableadmin.googleapis.com, ..., appProfileId=, userAgent=hbase-1.4.1, credentialType=DefaultCredentials, port=443, dataChannelCount=32, retryOptions=RetryOptions{retriesEnabled=true, allowRetriesWithoutTimestamp=false, statusToRetryOn=[DEADLINE_EXCEEDED, UNAVAILABLE, UNAUTHENTICATED, ABORTED], initialBackoffMillis=5, maxElapsedBackoffMillis=60000, backoffMultiplier=2.0, streamingBufferSize=60, readPartialRowTimeoutMillis=60000, maxScanTimeoutRetries=3}, bulkOptions=BulkOptions{asyncMutatorCount=2, useBulkApi=true, bulkMaxKeyCount=125, bulkMaxRequestSize=1048576, autoflushMs=0, maxInflightRpcs=320, maxMemory=143183052, enableBulkMutationThrottling=false, bulkMutationRpcTargetMs=100}, callOptionsConfig=CallOptionsConfig{useTimeout=false, shortRpcTimeoutMs=60000, longRpcTimeoutMs=600000}, usePlaintextNegotiation=false}.
Refreshing the OAuth token
Are there any options I can consider; other than using the BitTable emulator? I had some trouble getting that running a while back; so must try again.
Thanks,
Brent
As Solomon said above, please open a Google Cloud support ticket to resolve this.

Twilio IP Messaging token issue

I'm setting up an iOS app to use the IP Messaging and video calling apis. I'm able to connect, create channels and setup a video call if I manually create hard-coded tokens for the app. However, if I want to use the PHP server (as described here https://www.twilio.com/docs/api/ip-messaging/guides/quickstart-ios) then I always get an error and it can't connect anymore.
I'm attaching a screenshot of what I see when I hit the http://localhost:8080 address which seems to produce a 500 Internal error on this URL: https://cds.twilio.com/v2/Streams
Thanks so much!
After much time spent on this I decided to try the node backend instead - under other server-side languages of the PHP and I have it running in 2 minutes! I used the exact same credentials as the ones that I was using on the PHP config file so either my PHP environment has something strange or the PHP backend needs some fixing. In any case, I'm able to move forward using the node backend, so if you run into the same issue just try node instead of PHP. woohoo!

Connecting Sails Socket IO to Sails server running in consul

There's this μService architecture running as the backend, with a consul instance managing all the services. There's a particular server, A made with Sails, and with some relevant socket logic I'd like to use from another service B using sails.io.
Each service is running in its own Docker container, but they all connect to the same network.
So, when developing, I run the A container locally and simulate service B with a node script, with the logic showed here. The service URL is quite simple given that I'm just running the container with an open port, so the URL sails.io uses to connect is localhost:PORT. Everything here well.
The problem comes when service A is run in the μService architecture. Each service runs in its own URL, for example backend.com/api/SERVICE_NAME, acting like a namespace, with every route under the namespace actually hitting the SERVICE_NAME service. So now sails.io has issues connecting to service A, I presume, because of the change in route.
Thes are all the variations I've tried given const io = sailsIOClient(socketIOClient);
io.sails.url = 'http://backend.com/api/SERVICE_NAME';
then
io.sails.url = 'http://backend.com';
io.sails.path = '/api/SERVICE_NAME'
then
io.sails.url = 'http://backend.com';
io.sails.path = '/api/SERVICE_NAME/socket.io/'
Then I stumbled with this that refers to a path argument on the connect function of socket.io (here's the specific). I tried with that, setting io.sails.autoConnect to false and calling io.sails.connect() but I'm not being able to connect to the Sails app.
Socket is trying to reconnect to Sails...
_-|>_- (attempt #293)
I'm fairly certain the issue is that the client io can't reach the correct route to find the Sails app because of the architecture is set up.
Has someone dealt with a similar scenario? Suggestions are greatly appreciated.

SignalR Client - The remote server returned an error (401 Unauthorized)

Premise
I'm attempting to make a windows service act as a signalR client to a web server (MVC3 project running on IIS Express). When trying to connect to the server, a 401 Unauthorized is returned.
Now, as far as I understand, the windows service runs under the account NETWORK_SERVICE, and it makes sense that this is not a valid user name to connect to the IIS. However, I've tried configuring SignalR in the following way:
Init
private static Connection WebUIConnection = new Connection("http://localhost:54193/IISWebsite");
Set credentials
WebUIConnection.Credentials = new System.Net.NetworkCredential("?", "?")
The settings of the IIS:
The IIS is almost a standard MVC3 project, and it has windows authentication enabled.
What I've tried
I've tried setting SignalR's credentials as my local windows username + pw, and also tried using the local network AD uname + pw, but I don't see this as being the way to do it.
So what I'm asking is, what should I consider when I try to make my windows service act as a client to the signalR-server, and is there a way to configure IIS to give client access to the Network_Service user? Is it in fact possible to make a windows service act as a client to a web server running in IIS like I'm trying to do?
Thanks,
Lari
I was able to solve what seems to be the problem. With the SignalR.Client the URL you need to give in the connection string looks like this:
private static Connection WebUIConnection = new Connection("http://localhost:54193/IISWebsite/signalr/hubs");
In addition to this I had to provide it with my local admin username and password for it to be able to connect. This is not how it should be done I feel, and I'd appreciate if anyone can enlighten me on how to make the network user have access to IIS from a local machine.
However, I think making a separate administrator account and making my windows service run under that account in the production environment is a solution I'm willing to accept. This way, it will be able to connect to the local IIS without a hitch.
Hope this information is helpful to others :)
Lari
If you're using hubs then that code is incorrect. There's a HubConnection you should be using. More info here:
https://github.com/SignalR/SignalR/wiki/SignalR-Client-Hubs

Resources