Integrations: AWS OIDC - ListDatabases action#24460
Conversation
bc53c4d to
ef52fa7
Compare
55e0ec1 to
6e53f6d
Compare
|
@marcoandredinis - this PR will require admin approval to merge due to its size. Consider breaking it up into a series smaller changes. |
add3077 to
0702e0f
Compare
r0mant
left a comment
There was a problem hiding this comment.
Nice job on the test coverage here 👍
Left a few suggestions on reusing existing resource representations and simplifying the API a bit.
There was a problem hiding this comment.
Can we just convert it to types.Database resource, we already have a function for that somewhere? Why add another representation of the database. You can just add missing fields (like status) to our resource for example as labels or something.
There was a problem hiding this comment.
We are using aws go sdk v1 for rds api everywhere else
teleport/lib/cloud/aws/tags_helpers.go
Line 23 in 05aa048
I don't think I can re-use such helpers
I decided to use v2, so most things will not be compatible.
Now, I'm wondering if I should switch to the v1 of the go sdk 🤔
There was a problem hiding this comment.
I've created new helpers using the aws sdk go v2 👍
There was a problem hiding this comment.
Why did you decide to go with this approach of having a generic "execute action" API instead of just having an API specifically for fetching RDS databases/clusters? I'm just thinking this feels like trying to design another "protocol" on top of our API so the API response can also be different based on the "action" you're requesting, etc.
I'd go for a simpler approach with just separate handlers, would be easier to see all API surface as well based on the registered handlers. What do you think?
There was a problem hiding this comment.
Sure 👍
I'll create one endpoint per action.
So in this case we'll have
h.POST("/webapi/sites/:site/integrations/:name/action/list_databases", h.WithClusterAuth(h.awsOIDCListDatabases))There was a problem hiding this comment.
Why do we need "action" at all? Could we just do
/webapi/sites/:site/integrations/aws/:name/databases
Btw, I'd also add /aws to the path to be able to differentiate between handlers for different integrations.
There was a problem hiding this comment.
Looks good 👍
I've just replace aws with aws-oidc because that's the name we are using everywhere
There was a problem hiding this comment.
Similar question as above about these new resources, can web UI use exiting database types we already have defined? cc @kimlisa Just trying to avoid having too many representations of the same thing.
There was a problem hiding this comment.
i think it makes sense to me to be explicit like this, a type that tells me that this isn't a teleport database resource
that said, we can re-use the existing web/ui database type (linked below) and extend it to include fields unique to the aws database if we really want to (in the end it doesn't matter much as long as the front get the values we need b/c the frontend will customize it further to suite the needs of the component that needs it anyways):
Line 227 in e2df4a3
no strong opinions
There was a problem hiding this comment.
I've added all the types.AWS fields and the Status as well (which comes from a label).
0702e0f to
75f96f2
Compare
f7e7d90 to
d858b7e
Compare
There was a problem hiding this comment.
i'm confused why this type is necessary? can't we use the pb type from the get go? this is what i see in other places, so i am not sure which method/pattern to stick with (or what makes this one the exception)
There was a problem hiding this comment.
I did it only to implement the CheckAndSetDefaults
The pb type is created here: api/gen/proto/go/teleport/integration/v1/integration_service.pb.go
I was trying to avoid adding custom code close in those auto generated folders.
There was a problem hiding this comment.
think you meant to put this on top of the mockCAGetter that it is used to implement the CAGetter interface?
There was a problem hiding this comment.
Yes! Thank you.
There was a problem hiding this comment.
i'm sorry if i'm butchering my understanding, but regarding Multi-AZ DB clusters, it sounds like for example, if i want a complete list of ALL mysql rds items (whether that's instance or cluster), i would need to query twice?
So I need to make two api calls like this:
first request: get mysql instances
rdsType: 'instance',
engines: ['mysql', 'mariadb'],second request: get mysql clusters
rdsType: 'cluster',
engines: ['mysql', 'mariadb'],or instead of combining all of this into one list, would it make more sense to do a dropdown menu and let user choose if they want a list of instances? or list of clusters?
There was a problem hiding this comment.
I think we must have separate tiles for each.
One for Aurora/Cluster MySQL/MariaDB and another one for RDS MySQL/MariaDB.
Looking at the designs, we have them together as AWS | RDS & Aurora
I'll ask the design team if that's ok to have them apart
The issue here is pagination
AWS provides an API for instances and another one for clusters
When doing pagination we only have one nextToken/nextKey/marker and that is either going to be used for Instances or Clusters.
We can make things work ™️ , but we'll need another abstraction
a325e40 to
016ebe7
Compare
This PR adds a new Action for the AWSOIDC Integration: ListDatabases
The goal of this action is to provide the User a list of RDS Databases
from which the User will pick one to be added as a Teleport Database
Resource.
This way, the user doesn't need to copy/paste DB name, endpoints and
labels.
Before being able to call this action, the User has to set up an AWS
OIDC integration.
How does it work:
```
Client (web app)
│ ▲
│ │4. Returns list of DBs
1. List Databases │ │ (name, tags, status, endpoint)
│ │
│ │
│ │
│ │
▼ │ 3. rds.DescribeDBInstances
┌───────────┴────┐ (auth: token) ┌─────────┐
│ ├─────────────────────────────────►│ │
│ Teleport Proxy │ │ AWS │
│ │ 3.1. Get OIDC Config │ │
│ │◄─────────────────────────────────┤ │
│ │ 3.2. Get RSA Public Key │ │
│ │◄─────────────────────────────────┤ ├─────────┐ 3.3.
│ │ │ │ │Validates token signature
│ │ │ │ │with received public key
│ │ 3.4 Returns list of DBs │ │◄────────┘
│ │◄─────────────────────────────────┤ │
└─┬──────────────┘ └─────────┘
│
│ 2. Sign Token
│
▼
┌───────────────────┐
│ │
│ Teleport Auth │
│ RSA Private Key │
└───────────────────┘
```
016ebe7 to
cb5a180
Compare
|
@marcoandredinis See the table below for backport results.
|
This PR adds a new Action for the AWSOIDC Integration: ListDatabases
The goal of this action is to provide the User a list of RDS Databases
from which the User will pick one to be added as a Teleport Database
Resource.
This way, the user doesn't need to copy/paste DB name, endpoints and
labels.
Before being able to call this action, the User has to set up an AWS
OIDC integration.
How does it work:
Eg of an HTTP response from
4.{ "databases":[ { "name":"marcodb-test", "desc":"RDS instance in us-east-1", "protocol":"postgres", "type":"rds", "labels":[ { "name":"account-id", "value":"123456789012" }, { "name":"canBeDeleted", "value":"yes" }, { "name":"endpoint-type", "value":"instance" }, { "name":"engine", "value":"postgres" }, { "name":"engine-version", "value":"14.6" }, { "name":"env", "value":"test" }, { "name":"project", "value":"discover" }, { "name":"region", "value":"us-east-1" }, { "name":"status", "value":"available" }, { "name":"teleport.dev/origin", "value":"cloud" } ], "hostname":"marcodb-test.abcdef123456.us-east-1.rds.amazonaws.com", "uri":"marcodb-test.abcdef123456.us-east-1.rds.amazonaws.com:5432", "aws":{ "region":"us-east-1", "rds":{ "instance_id":"marcodb-test", "resource_id":"db-123456ABCEDF123456ABCEDF00", "iam_auth":false }, "account_id":"123456789012", "status":"available" } } ] }