Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ROX-12151: cloud accounts endpoint #517

Merged
merged 5 commits into from
Oct 28, 2022

Conversation

ivan-degtiarenko
Copy link
Contributor

@ivan-degtiarenko ivan-degtiarenko commented Oct 25, 2022

Description

Introduces the call to AMS client as well as new endpoint. The organization ID is taken from the caller's claims.

Checklist (Definition of Done)

  • Unit and integration tests added
  • Added test description under Test manual
  • Documentation added if necessary (i.e. changes to dev setup, test execution, ...)
  • CI and all relevant tests are passing
  • Add the ticket number to the PR title if available, i.e. ROX-12345: ...
  • Discussed security and business related topics privately. Will move any security and business related topics that arise to private communication channel.

Test manual

TODO: Add manual testing efforts

  1. ./fleet-manager serve --ocm-base-url=https://api.openshift.com --ocm-client-id-file=secrets/ocm-service.clientId --ocm-client-secret-file=secrets/ocm-service.clientSecret
  2. GET http://localhost:8000/api/rhacs/v1/cloud_accounts with rhacs-test-customer Bearer token
  3. Returned result:
{
    "cloudAccounts": [
        {
            "cloudAccountId": "<redacted>",
            "cloudProviderId": "aws"
        }
    ]
}

return nil, fmt.Errorf("error getting cloud accounts: %w", err)
}

quotaCostList.Items().Each(func(qc *amsv1.QuotaCost) bool {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will list all cloud accounts, right? We should filter here on the cloud accounts that are attached to our marketplace SKU, i.e. "quota_id": "cluster|rhinfra|rhacs|marketplace". Otherwise we'll also return cloud accounts that have purchased different products.

@@ -600,3 +602,26 @@ func (c client) GetQuotaCostsForProduct(organizationID, resourceName, product st

return res, nil
}

func (c *client) GetCustomerCloudAccounts(externalID string) ([]*amsv1.CloudAccount, error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a unit test for this function using the generated mocks?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean cloud_accounts_test.go for the endpoint handler? There's no way to mock sdkClient.Connection used in client.go

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm yes. I think you could write a unit test with the cloud_accounts_test.mock, and you could also take a look at https://github.com/stackrox/acs-fleet-manager/blob/main/internal/dinosaur/pkg/services/quota/ams_quota_service_test.go for how to mock the OCM client. With the latter you could test the SKU filter logic.

@@ -608,6 +608,37 @@ paths:
security:
- Bearer: []
summary: Returns the list of supported regions of the supported cloud provider
/api/rhacs/v1/cloud_accounts:
get:
operationId: getCloudAccounts

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The endpoint looks good to me. The only thing I'm wondering about is this operationId. @stehessel mentioned in his comment how to access the organization.id using ocm command. Is operationId supposed to be that? Also, accessing that id using the ocm command is helpful, but I can't do that through the browser so I'll need to find another way to do that. If you or @stehessel might know how that's possible, let me know. I am searching through https://api.openshift.com/ to see if there might be some API endpoint that might give me that information

Copy link

@sachaudh sachaudh Oct 25, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is /api/accounts_mgmt/v1/organizations the API i'm looking for? Looks like that gives me a list of organizations (there seems to be just one though). I see fields like id and external_id which seem relevant

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sachaudh organization.id will be extracted by fleet-manager from AMS using orgId provided in the Bearer token. The endpoint doesn't take any parameters.

operationId is swagger parameter that is used to uniquely identify the operation within the API spec:
https://swagger.io/docs/specification/paths-and-operations/

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, then I think that's fine with me. Thanks for adding the endpoint @ivan-degtiarenko 👍🏼

@ivan-degtiarenko ivan-degtiarenko changed the title [WIP] Ivan/rox 12151 aws accounts endpoint ROX-12151: cloud accounts endpoint Oct 25, 2022

func (c *client) GetCustomerCloudAccounts(externalID string, quotaIDs []string) ([]*amsv1.CloudAccount, error) {
var res []*amsv1.CloudAccount
organizationClient := c.connection.AccountsMgmt().V1().Organizations()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is already GetQuotaCostsForProduct - seems like it's what we want, it's only missing a fetchCloudAccounts=true flag. Maybe we could reuse this here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really - GetQuotaCostsForProduct does filtration by resourceName and product

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In principle that is what we also want. But I think you are right, we would want to filter for billing_model==marketplace as well. Easier to go the quota_id route then.

JwtCAFile = "test/support/jwt_ca.pem"
)

func TestGetSuccess(t *testing.T) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be good to test GetCustomerCloudAccounts as well, in particular testing that the filtering by resource id works. I think this is possible by mocking the other OCM client methods like QuotaCost (or GetQuotaCostsForProduct).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GetQuotaCostsForProduct can't be reused for the reasons mentioned above. I'm not sure how one can mock QuotaCost method on the organizationClient - it is created by Connection:
https://github.com/stackrox/acs-fleet-manager/blob/ivan%2FROX-12151-aws-accounts-endpoint/pkg/client/ocm/client.go#L608-L608

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm yes that is impractical, I thought I saw it in the method list of the client, but you are right it's not. That would leave us with mocks on http level, which maybe are supported via the "mock modes" (https://github.com/stackrox/acs-fleet-manager/blob/ivan/ROX-12151-aws-accounts-endpoint/pkg/client/ocm/config.go#L12). But probably a lot of effort for a simple feature...

func (h *cloudAccountsHandler) Get(w http.ResponseWriter, r *http.Request) {
cfg := &handlers.HandlerConfig{
Action: func() (i interface{}, serviceError *errors.ServiceError) {
ctx := r.Context()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you extract inside of this function (func() (i interface{}, serviceError *errors.ServiceError) { ... }, you could test it separately from the http related parts of Get. This would save you some http setup in the cloud_accounts_test.go.

@openshift-ci
Copy link
Contributor

openshift-ci bot commented Oct 27, 2022

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: ivan-degtiarenko, stehessel

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@ivan-degtiarenko ivan-degtiarenko force-pushed the ivan/ROX-12151-aws-accounts-endpoint branch from 886031e to a5c79f5 Compare October 28, 2022 00:17
@openshift-ci openshift-ci bot removed the lgtm label Oct 28, 2022
@openshift-ci
Copy link
Contributor

openshift-ci bot commented Oct 28, 2022

New changes are detected. LGTM label has been removed.

@ivan-degtiarenko ivan-degtiarenko merged commit faa8dc3 into main Oct 28, 2022
@ivan-degtiarenko ivan-degtiarenko deleted the ivan/ROX-12151-aws-accounts-endpoint branch October 28, 2022 02:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants