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

Add AppLens Client and Detector Endpoints #2243

Merged

Conversation

zacharyljones
Copy link
Contributor

@zacharyljones zacharyljones commented Jul 12, 2022

Which issue this PR addresses:

Feature 10651414

What this PR does / why we need it:

This PR adds API endpoints that will enable AppLens Detectors in the Diagnose & Solve Problems Blade in the Azure Portal for ARO clusters.

Test plan for issue:

I have tested that I am able to hit the appropriate AppLens endpoints locally and receive a 401: Unauthorized error. There is no way for me to fully test this change in my dev environment because the "public" AppLens endpoints exist within the AME tenant and cross-tenant communication is not allowed. It may be possible to setup a dev RP in the AME tenant, but this is a conversation that I will have with Red Hat/MS offline.

Is there any documentation that needs to be updated for this PR?

No, the AppLens team has generic documentation for performing this integration with any service (necessary api endpoints, AppLens service endpoints, etc.)

@@ -135,36 +135,17 @@ func (c *Cluster) Create(ctx context.Context, vnetResourceGroup, clusterName str
}

c.log.Infof("creating AAD application")
// This is for our CFS scenario where we do not have permissions to allow the RP to create it's own AAD application
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changes to this file were specific to a local development scenario and were accidentally committed. All changes to this file have been reverted.

@@ -135,14 +135,32 @@ func (c *Cluster) Create(ctx context.Context, vnetResourceGroup, clusterName str
}

c.log.Infof("creating AAD application")
appID, appSecret, err := c.createApplication(ctx, "aro-"+clusterName)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changes to this file were specific to a local development scenario and were accidentally committed. All changes to this file have been reverted.

@zacharyljones zacharyljones force-pushed the zjones/app_lens_detectors branch 2 times, most recently from 21a7e79 to 5807b66 Compare July 12, 2022 21:24
@zacharyljones
Copy link
Contributor Author

zacharyljones commented Jul 12, 2022

@weinong @coreyperkins FYSA

@zacharyljones
Copy link
Contributor Author

The AppLens Client was modeled after the Azure CosmosDB Client in the Azure SDK for Go. Unfortunately this new client cannot be added to the Azure SDK for Go, as the AppLens service is technically private and there is no need for end users to have access to the client.

@@ -79,6 +80,7 @@ type Interface interface {
Domain() string
FeatureIsSet(Feature) bool
FPAuthorizer(string, string) (refreshable.Authorizer, error)
FPNewClientCertificateCredential(string) (*azidentity.ClientCertificateCredential, error)
Copy link
Contributor

Choose a reason for hiding this comment

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

we should use azcore.TokenCredential interface

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I will take a look - the current FPauthorizer uses cert based authentication to AAD, so I thought that made the most sense at the time. After our conversation yesterday, it sounds like we want to use the FP certificates to create an azcore.TokenCredential and then authenticate to AppLens using that credential. Is that correct?

Copy link
Contributor

Choose a reason for hiding this comment

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

correct. that being said, azidentity.ClientCertificateCredential is also azcore.TokenCredential

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I attempted to use the azcore.TokenCredential interface, but ran into an issue with code gen. The mock env file that gets generated imports github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared instead of just github.com/Azure/azure-sdk-for-go/sdk/azcore. Similarly, all references to azcore.TokenCredential are replaced with shared.TokenCredential. This causes go validation to fail, unit tests to fail, etc.

A bit of research turned up this azure-sdk-for-go issue. Apparently this is a bug/issue with how older versions of the SDK
export symbols. Some aspects of this issue have been fixed but none of those changes are available in the go 1.17 compatible version of the SDK that I am using.

Sticking with azidentity.ClientCertificateCredential for now.

@@ -102,3 +113,20 @@ func (a *azureActions) VMResize(ctx context.Context, vmName string, size string)
vm.HardwareProfile.VMSize = mgmtcompute.VirtualMachineSizeTypes(size)
return a.virtualMachines.CreateOrUpdateAndWait(ctx, clusterRGName, vmName, vm)
}

func (a *azureActions) AppLensGetDetector(ctx context.Context, detectorId string) ([]byte, error) {
resp, err := a.appLens.GetDetector(ctx, &applens.GetDetectorOptions{ResourceID: a.oc.Properties.ClusterProfile.ResourceGroupID, DetectorID: detectorId})
Copy link
Contributor

Choose a reason for hiding this comment

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

ResourceGroupID?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated to use cluster resource id, and not cluster resource group resource id

var _ AppLensClient = &appLensClient{}

// NewAppLensClient returns a new AppLensClient
func NewAppLensClient(env *azureclient.AROEnvironment, clientCertCred *azidentity.ClientCertificateCredential) AppLensClient {
Copy link
Contributor

Choose a reason for hiding this comment

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

let's also use azcore.TokenCredential

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 want this in addition to azidentity.ClientCertificateCredential, or do you want me to replace azidentity.ClientCertificateCredential with azcore.TokenCredential?

Copy link
Contributor

Choose a reason for hiding this comment

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

azidentity.ClientCertificateCredential is the implementation of azcore.TokenCredential interface

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Refer to previous comment

return nil, err
}

return []string{fmt.Sprintf("%s://%s/.default", u.Scheme, u.Hostname())}, nil
Copy link
Contributor

Choose a reason for hiding this comment

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

i'm pretty sure the endpoint is not the scope.

Copy link
Contributor Author

@zacharyljones zacharyljones Jul 13, 2022

Choose a reason for hiding this comment

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

This was copied over from the Cosmos client - I figured I would resolve any issues related to the scope during testing as I wasn't sure whether it would be needed or not. Do you think the scope should be something else, or removed altogether?

Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Understood - with that information I was able to use the appropriate scopes provided by the AppLens team. The code for creating the scope from the target endpoint has been removed.

ctx context.Context,
requestOptions appLensRequestOptions,
requestEnricher func(*policy.Request)) (*http.Response, error) {
req, err := c.createRequest(ctx, http.MethodGet, requestOptions, requestEnricher)
Copy link
Contributor

Choose a reason for hiding this comment

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

AppLens api is Post, iirc

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oof - you are correct. I will swap the get method for a post and update relevant unit tests. MTF.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Client updated to use Post. Unit tests also updated.

@github-actions
Copy link

Please rebase pull request.

@github-actions github-actions bot added the needs-rebase branch needs a rebase label Jul 13, 2022
@weinong
Copy link
Contributor

weinong commented Jul 13, 2022

can you also add user agent please?

}

func (a *azureActions) AppLensListDetectors(ctx context.Context) ([]byte, error) {
resp, err := a.appLens.ListDetectors(ctx, &applens.ListDetectorsOptions{ResourceID: a.oc.Properties.ClusterProfile.ResourceGroupID})
Copy link
Contributor

Choose a reason for hiding this comment

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

same here. using resource group ID seems wrong.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated to use cluster resource id, and not cluster resource group resource id

@github-actions github-actions bot removed the needs-rebase branch needs a rebase label Jul 13, 2022
@zacharyljones
Copy link
Contributor Author

can you also add user agent please?

@weinong Can you elaborate on this? I see that it is added in AKS, but I do not see it in the AppLens example. What does the user agent afford us?

@zacharyljones zacharyljones force-pushed the zjones/app_lens_detectors branch 4 times, most recently from 82b2651 to 3707b8d Compare October 18, 2022 15:54
@zacharyljones zacharyljones force-pushed the zjones/app_lens_detectors branch 2 times, most recently from d0e2b40 to 1aaa832 Compare October 21, 2022 16:46
@rogbas
Copy link
Collaborator

rogbas commented Dec 6, 2022

I'm assuming AppLens relies on an Azure service of same name, correct? Have we checked if it is available in all the Azure regions we support? cc @weinong

@weinong
Copy link
Contributor

weinong commented Dec 7, 2022

I'm assuming AppLens relies on an Azure service of same name, correct? Have we checked if it is available in all the Azure regions we support? cc @weinong

yes, it's available in public and fairfax

return nil, err
}

successResponse := (response.StatusCode >= 200 && response.StatusCode < 300) || response.StatusCode == 304
Copy link
Contributor

Choose a reason for hiding this comment

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

Why are we expecting to receive a variety of response codes from applens for a successful call?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Agreed, I think it would be better to have a list of all success responses from applens and and evaluate based on that list rather than have a huge range.

@@ -33,6 +40,9 @@ var (
ActualCloudName: "AzureUSGovernment",
GenevaMonitoringEndpoint: "https://gcs.monitoring.core.usgovcloudapi.net/",
AppSuffix: "aro.azure.us",
AppLensEndpoint: "https://diag-runtimehost-prod-bn1-001.azurewebsites.us/api/invoke",
AppLensScope: "https://microsoft.onmicrosoft.com/runtimehost",
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is the scope here a URL?

@s-amann
Copy link
Contributor

s-amann commented Dec 7, 2022

/azp run ci

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@cfsmikedrum
Copy link
Contributor

@s-amann, the rebase is complete

Zach Jones and others added 6 commits December 15, 2022 15:05
* Change to using the environment AppLens tenant ID

Add the tenant ID values for the clouds

* Remove the blank line

Co-authored-by: Nont <nthanonchai@microsoft.com>
Also remove empty line from go.mod
Copy link
Collaborator

@cadenmarchese cadenmarchese left a comment

Choose a reason for hiding this comment

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

Some outstanding comments here, but as discussed I'll merge this to unblock AppLens onboarding @s-amann

return nil, err
}

successResponse := (response.StatusCode >= 200 && response.StatusCode < 300) || response.StatusCode == 304
Copy link
Collaborator

Choose a reason for hiding this comment

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

Agreed, I think it would be better to have a list of all success responses from applens and and evaluate based on that list rather than have a huge range.

@cadenmarchese cadenmarchese merged commit fe9017d into Azure:master Dec 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants