I have a bound Postgres service to my spring application in CF (Cloud foundry)
The VCAPS env available are as following:
"postgresql": [
{
"binding_name": null,
"credentials": {
"dbname": "JDusZ6EpE1ixbTKS",
"end_points": [
{
"host": "10.11.241.2",
"network_id": "SF",
"port": "46371"
}
],
"hostname": "10.11.241.2",
"password": "SuVzOf2m5L5oNYSG",
"port": "46371",
"ports": {
"5432/tcp": "46371"
},
"uri": "postgres://eyv6avf27X9Z55Gx:SuVzOf2m5L5oNYSG#10.11.241.2:46371/JDusZ6EpE1ixbTKS",
"username": "eyv6avf27X9Z55Gx"
},
"instance_name": "mypostgres",
"label": "postgresql",
"name": "mypostgres",
"plan": "v9.6-dev",
"provider": null,
"syslog_drain_url": null,
"tags": [
"postgresql",
"relational"
],
"volume_mounts": []
}
],
I need to modefy the value of the uri to include also the current schema, I guess it needs to be as:
"uri": "postgres://eyv6avf27X9Z55Gx:SuVzOf2m5L5oNYSG#10.11.241.2:46371/JDusZ6EpE1ixbTKS?currentSchema=mycurrentschema"
Is this something possible to do? and If not what is the best practice to assign current schema for a spring app?
Thanks in advance
You have a few options.
You can talk to your service provider, the operator of the service broker from which you are obtaining your service. The service broker is the one that sets the credentials, so you could ask them to include the schema by default.
You can create a service key with cf create-service-key. The service key is like a service binding, but free floating so it's not attached to your app. It just exists as long as the service key exists. You can then create a user provided service, with cf cups and manually set whatever credentials or uri you require for your app. The downside of this approach is that you have to do a little more work to manage the service information.
You can read the current uri into your application and modify it before creating your DataSource. This is not particularly easy if you are using Spring Cloud Connectors because it handles creating the DataSource for you. I would not recommend using SCC.
Instead you can do this with the Spring Boot CloudFoundryVcapEnvironmentPostProcessor and property place holders. See the referenced Javadoc for how that works.
The other option is to use java-cvenv. That provides you with an easy way to obtain credentials information, like the URL and use that to create your own DataSource, which allows you to make slight modifications to things like the URL, if necessary.
Hope that helps!
Related
We have a range of apps deployed to our Fiori Launchpad (via an mta) file on Cloud Foundry.
I came across this blog that describes setting up role access on an app by app basis.
Configuring Roles – SAP Fiori Launchpad Cloudfoundry | SAP Blogs.
Firstly, I setup approuter/xs-app.json as follows. Note this has as single config_admin scope as opposed to the 2 (approver and user) in the blog. The reason for this is we only need a single configurable role at the moment, so I'm making the assumption we only need a single scope.
Does the below snippet look correct? I've used "srv_api" as the destination from the blog, but not sure If it needs to be something else.
{
"authenticationMethod": "route",
"welcomeFile": "/cp.portal",
"routes": [
{
"source": "^/catalog(.*)$",
"target": "/catalog$1",
"destination": "srv_api",
"authenticationType": "xsuaa",
"scope": {
"GET": ["$XSAPPNAME.config_admin"],
"PATCH": ["$XSAPPNAME.config_admin"],
"POST": ["$XSAPPNAME.config_admin"],
"PUT": ["$XSAPPNAME.config_admin"],
"DELETE": ["$XSAPPNAME.config_admin"],
"default": ["$XSAPPNAME.config_admin"]
}
}
],
"logout": {
"logoutEndpoint": "/do/logout"
}
}
Next up, xs-security.json in the project root.
{
"xsappname": "demo",
"tenant-mode": "dedicated",
"description": "Security profile of called application",
"scopes": [
{
"name": "uaa.user",
"description": "UAA"
},
{
"name": "$XSAPPNAME.config_admin",
"description": "UAA configuration admin"
}
],
"role-templates": [
{
"name": "Token_Exchange",
"description": "UAA",
"scope-references": ["uaa.user"]
},
{
"name": "ADMIN_USER",
"description": "UAA ADMIN_USER",
"scope-references": ["uaa.config_admin"]
}
]
}
... and finally the manifest.json of the app I would like to apply the role to:
"sap.platform.cf": { "oAuthScopes": ["$XSAPPNAME.config_admin"] }
The app exists in a Group containing only that app.
When deployed to SAP Cloud Foundry, the Group and app are hidden. Fine I thought, just needs the role configured on the BTP side?
In BTP, I setup the role collection with my user, and the the two roles, ADMIN_USER and Token_Exchange, which were deployed correctly to BTP in the previous step.
However, the app and it's Catalog are still hidden from view on the Fiori Launchpad. The only apps that do appear are the one's without the "sap.platform.cf" manifest entry.
Am I approaching this the correct way? Have I missed something?
Or do I need to setup two separate scope, as in the guide, and include the relevant scope in each and every app?
*Note - I've tried setting up the user without the Token_Exhange role, with the same result.
The answer is a typo in xs-security.json
Should be: "scope-references": ["$XSAPPNAME.config_admin"]
Currently AWS AppSync provides an option to add test context to test your resolver to make sure everything is correct. However, because I am using API Key for authentication, I'm not sure of a way to set this in the request mapping template so that the test context can run and I can test the validity of my API (especially since this is the only auth that doesn't have an identity section in the test context)? Can anyone help?
You are correct in the fact that API Key Authorization mode does not populate the identity, even when you are calling your API from a client.
However, you can still add an identity object in your test context. To do this, you need to:
Get the authorization mode you will be using in the future (IAM, Cognito, OIDC).
Find the fields that authorization mode provides in the ctx.identity. You can find that here: Resolver Context Reference
Add those fields to your test context. For example, IAM test context might look like this:
{
"identity": {
"accountId": "my aws account",
"cognitoIdentityPoolId": "string",
"cognitoIdentityId": "string",
"sourceIp": ["string"],
"username": "string",
"userArn": "string"
},
"arguments": {},
"source": {
"lambda": "Hello, world!",
"testCtx": "Hello, world!"
},
"result": "Hello, world!"
}
The request mapping template could look like this:
{
"account: "$ctx.identity.accountId"
}
and the evaluated request mapping template would look like this when your test context is run:
{
"account: "my aws account"
}
Note: You may also just want to switch your API to the authorization mode you plan on using, and then try queries as a logged-in user.
I am registering an external service in consul through Catalog API http://127.0.0.1:8500/v1/catalog/register with a payload as follows :
{
"Datacenter": "dc1",
"Node": "pedram",
"Address": "www.google.com",
"Service": {
"ID": "google",
"Service": "google",
"Address": "www.google.com",
"Port": 80
},
"Check": {
"Node": "pedram",
"CheckID": "service:google",
"Status": "passing",
"ServiceID": "google",
"script": "curl www.google.com > /dev/null 2>&1",
"interval": "10s"
}
}
The external service registers successfully and I see it in the list of registered services, but after a while it disappears. It seems that it's got unregistered automatically.
I am running the consul in -dev mode.
What's the problem?
I found that I should register external services in separate node. My application's local services are getting registered in a node named
"Node": "pedram"
when I register external services in this node, they will be get removed automatically.
But when I register my external services in a new node, all the new external services are get registered durably and ready to be used as all other local services.
my new payload is as follows :
{
"Datacenter": "dc1",
"Node": "newNode",
"Address": "www.google.com",
"Service": {
"ID": "google",
"Service": "google",
"Address": "www.google.com",
"Port": 80
},
"Check": {
"Node": "newNode",
"CheckID": "service:google",
"Status": "passing",
"ServiceID": "google"
}
}
This is excepted behavior. In Consul Anti-Entropy docs
If any services or checks exist in the catalog that the agent is not aware of, they will be automatically removed to make the catalog reflect the proper set of services and health information for that agent. Consul treats the state of the agent as authoritative; if there are any differences between the agent and catalog view, the agent-local view will always be used.
In your settings, the agent in the host 'pedram' didn't aware of the service register. so the anti-entropy strategy removes the service.
You shouldn't be using -dev mode, except for testing/playing around. for your health check, I'd recommend not using a "script": "curl www.google.com > /dev/null 2>&1",
Instead I'd recommend using a http health check:
"http": "https://www.google.com",
More about health checks is available here: https://www.consul.io/docs/agent/checks.html
Also, you should probably move to HTTPS (on port 443) if you can.
it also might help to save this as a .JSON file, and let consul read it as part of it's startup, as I'm guessing you want this to be a long-running external service. You can do that with a command like:
/usr/local/bin/consul agent -config-dir=/etc/consul/consul.d
and every .json file in /etc/consul/consul.d/ will be read as part of it's config. If you change the files, consul reload will restart.
I'd make those changes(not run in dev mode, etc) and see if the problem still exists. I'm guessing it won't.
When creating an unmanaged instance group through GCP Console, I can see the REST request as:
POST https://www.googleapis.com/compute/v1/projects/my-project/zones/us-east1-d/instanceGroups
{
"name": "ig-web",
"network": "https://www.googleapis.com/compute/v1/projects/my-project/global/networks/nomad-network",
"namedPorts": [
{
"name": "http",
"port": 11080
}
]
}
However, according to the API docs and client library generated code, one has no way to set the network URL.
Anyone care to clarify?
It's actually a documentation bug. The following will work:
op, err := gce.service.InstanceGroups.Insert(projectID, zone, &compute.InstanceGroup{
Name: name,
NamedPorts: namedPorts,
Network: networkURL}).Do()
I use GCE V1 rest api to launch instances. I rarely use google developer console. I created windows VM instance through rest api. I passed windows initial username and password in metadata property. Windows VM created successfully. I also able to get those credentials in response, which I sent while creating VM. But I couldn't connect the VM using that username and password. I read the doc about how to reset password from developer console. It works fine. But we would like to rest apis for all. I mean to created/manage GCE resources. So can anyone help to fix this issue?
The image I used to launch a vm is "windows-server-2012-r2-dc-v20150511"
"metadata": {
"items": [
{
"key": "gce-initial-windows-user",
"value": "administrator"
},
{
"key": "gce-initial-windows-password",
"value": "twxsFL3U-/,*"
}
]
}
Note: I created many VMs through rest api. All instances have the same issue. When reseting the password from developer console, it works.
The credentials didn't work. I am able to reset them from developer console. But that will not fix my problem. Because we have our own system to launch VMs and other services. For that I'm building a connector. Here is the sample request I send from node.js script.
Request :
***********
options : {
"host": "www.googleapis.com",
"path": "/compute/v1/projects/project-id/zones/us-central1-f/instances",
"method": "POST",
"headers": {
"Authorization": "Bearer ya29.lQGsX8hwdWKaDDwOFnDIZB49eir-c2TUBqYpaVvir7C430Quy8kIWsL4rXv7qjSVQZJKK5e1BdxNug",
"Content-Type": "application/json charset=utf-8"
}
}
body : {
"name": "rin2qvxkz-e",
"zone": "https://www.googleapis.com/compute/v1/projects/project-id/zones/us-central1-f",
"machineType": "https://www.googleapis.com/compute/v1/projects/project-id/zones/us-central1-f/machineTypes/n1-standard-2",
"metadata": {
"items": [
{
"key": "gce-initial-windows-user",
"value": "administrator"
},
{
"key": "gce-initial-windows-password",
"value": "%1zuV27$.:?*"
}
]
},
"tags": {
"items": [
"default"
]
},
"disks": [
{
"type": "PERSISTENT",
"boot": true,
"mode": "READ_WRITE",
"deviceName": "rin2qvxkz-e",
"autoDelete": true,
"initializeParams": {
"sourceImage": "https://www.googleapis.com/compute/v1/projects/windows-cloud/global/images/windows-server-2012-r2-dc-v20150511",
"diskType": "https://www.googleapis.com/compute/v1/projects/project-id/zones/us-central1-f/diskTypes/pd-standard"
}
}
],
"canIpForward": false,
"networkInterfaces": [
{
"network": "https://www.googleapis.com/compute/v1/projects/project-id/global/networks/default",
"accessConfigs": [
{
"name": "External NAT",
"type": "ONE_TO_ONE_NAT"
}
]
}
],
"description": "rin2qvxkz-e",
"scheduling": {
"preemptible": false,
"onHostMaintenance": "MIGRATE",
"automaticRestart": true
}
}
Thanks.
You are using a new Windows image "windows-server-2012-r2-dc-v20150511" with an updated GCEAgent that doesn't look at the gce-initial-windows-user/gce-initial-windows-password instance metadata keys which were used by the old authentication scheme.
Here are explanations of how the new authentication works, starting from the "windows-server-2012-r2-dc-v20150511" image and onwards.
Please note that the initial Windows authentication and GCE API v1 are two separate topics and GCE API v1 has not changed as part of the authentication update.
The earlier answer didn't really explain when this changed. I did more research and found a note in the change log for Google Windows Images.
Metadata items gce-initial-windows-user and gce-initial-windows-password will no longer work for images v20150511 and later
https://cloud.google.com/compute/docs/release-notes-archive#february_2015
June 03, 2015
Updated Windows authentication process. Windows images v20150511 and
later will use the new scheme by default. gcloud will now generate a
random password for Windows login; it is no longer possible to
manually set a Windows password through gcloud but you can set a
custom password in the instance.
Here are some links that detail how to Add users to windows Images now
You can use the gcloud command line tool
https://cloud.google.com/sdk/gcloud/reference/compute/reset-windows-password
gcloud compute reset-windows-password INSTANCE_NAME [--user=USER]
[--zone=ZONE] [GCLOUD_WIDE_FLAG …]
You can call the API, They give GO and Python examples
They also detail a Step-By-Step manual process, in case you want more details
https://cloud.google.com/compute/docs/instances/windows/automate-pw-generation