Azure / azure-sdk-for-net

This repository is for active development of the Azure SDK for .NET. For consumers of the SDK we recommend visiting our public developer docs at https://learn.microsoft.com/dotnet/azure/ or our versioned developer docs at https://azure.github.io/azure-sdk-for-net.
MIT License
5.53k stars 4.82k forks source link

Documentation is in need of significant improvement #36309

Open InteXX opened 1 year ago

InteXX commented 1 year ago

There's no indication of how to use this class, what it does or even how to get to it (i.e. it has no accessible constructor). Unfortunately, sample code for the SDK in general is sorely lacking; sparse documentation like this is not helpful either.

I need to use the SDK to upload and install a third-party TLS certificate on an existing App Service, a pretty common task. I've spent two full days searching, but I'm coming up empty.

Flying blind with no code samples or usage guidance is frustrating.


Document Details

Do not edit this section. It is required for learn.microsoft.com ➟ GitHub issue linking.

jsquire commented 1 year ago

Thank you for your feedback. Tagging and routing to the team member best able to assist.

InteXX commented 1 year ago

Very good, thank you.

ArthurMa1978 commented 1 year ago

@InteXX the Microsoft.Azure.Management.WebSites is the old SDK which is being deprecated, please move to our new SDK for App Service.

InteXX commented 1 year ago

@ArthurMa1978

Thank you for your quick reply.

Pardon me, I didn't notice the namespace in the topic that I reported. Yes, that reference is indeed for the old SDK.

Nevertheless, I can assure you that I'm using the new version in my code. The type names are the same in this case, which is what threw me off a bit.

But in the end, the new documentation suffers from the same problem.

The problem is that there's no guidance on how to actually use the SDK. The few published sample applications are sharply limited in nature, and the official documentation provides no insight into its use—only member declarations and type hierarchies. That's a lot to wade through and not much to go on. A couple of lines of sample code per topic would be very helpful.

We're flying blind out here, and I'm sad to report that it's not going so well.

How can I use the new SDK to upload and install a third-party TLS certificate to an App Service? I should think this to be a fairly common scenario.

Thanks again.

InteXX commented 1 year ago

@ArthurMa1978

I found an illustration of the problem.

Review this documentation; you'll note that where the guidance states "see example," there is no example nor is there a link to any example.

I've opened a separate issue for that page.

InteXX commented 1 year ago

@ArthurMa1978

What is the SDK equivalent of this REST API?

Unfortunately, the SDK is so poorly documented that—after two full days of digging—I finally have to ask.

Neutrino-Sunset commented 1 year ago

I'm in the same boat. Trying to work out how to use the SDK to enumerate ServicePrincipals to identify client secrets that are soon to expire. After 2 days of research I can't even work out which library I should be using!

InteXX commented 1 year ago

@Neutrino-Sunset

I feel your pain.

As it turns out, however, there exists an absolute bounty of SDK code samples, tucked away in a dark corner and hidden from easy discovery. The documentation team really needs to have a look at this situation.

It turns out that each namespace has its own rich collection of samples, e.g.:

https://github.com/Azure/azure-sdk-for-net/tree/main/sdk/websites/Azure.ResourceManager.AppService/samples

Thanks to a timely tip by SiddeshDesai, I was able to work out the solution to my own problem.

Your case, however, is a little bit different (and I'm going to be needing the same thing myself soon). It seems that the functionality we're after is in the Graph SDK, not the Azure SDK.

Here's a roughed-up sample that gets us started:

Private Async Function ShowExpiringSecrets() As Task
  Dim oCredentialAction As Action(Of PasswordCredential)
  Dim oPrincipalAction As Action(Of ServicePrincipal)
  Dim oGraphClient As GraphServiceClient
  Dim oPrincipals As List(Of ServicePrincipal)
  Dim oCredential As DefaultAzureCredential
  Dim oResponse As ServicePrincipalCollectionResponse
  Dim oOptions As TokenCredentialOptions
  Dim aScopes As String()

  aScopes = New String() {$"{My.Resources.MsGraphEndPoint}.default"}
  oOptions = New TokenCredentialOptions With {.AuthorityHost = AzureAuthorityHosts.AzurePublicCloud}
  oCredential = New DefaultAzureCredential
  oGraphClient = New GraphServiceClient(oCredential, aScopes)
  oResponse = Await oGraphClient.ServicePrincipals.GetAsync

  oCredentialAction = Sub(Credential)
                        If Credential.EndDateTime < Date.UtcNow.AddDays(30) Then
                          Console.WriteLine($"{Credential.DisplayName} - {Credential.EndDateTime}")
                        End If
                      End Sub

  oPrincipalAction = Sub(Principal) Principal.PasswordCredentials.ForEach(oCredentialAction)
  oPrincipals = oResponse.Value.OrderBy(Function(Principal) Principal.DisplayName).ToList

  oPrincipals.ForEach(oPrincipalAction)
End Function

Unfortunately, it doesn't go all the way. For some reason the PasswordCredentials list for each ServicePrincipal is empty, even when a ClientSecret is configured in the portal. Same with KeyCredentials.

I haven't figured that one out yet, but I'm still working on it. You may wish to follow this question.

I'll continue to post my progress here.

InteXX commented 1 year ago

@Neutrino-Sunset

OK... we have to get Applications, not ServicePrincipals.

Like so:

Private Async Function ShowExpiringSecrets() As Task
  Dim oGraphClient As GraphServiceClient
  Dim oCredential As DefaultAzureCredential
  Dim oResponse As ApplicationCollectionResponse
  Dim oSecret As PasswordCredential
  Dim oApps As List(Of Application)
  Dim oApp As Application

  oCredential = New DefaultAzureCredential
  oGraphClient = New GraphServiceClient(oCredential)
  oResponse = Await oGraphClient.Applications.GetAsync
  oApps = oResponse.Value.OrderBy(Function(Application) Application.DisplayName).ToList

  For Each oApp In oApps
    For Each oSecret In oApp.PasswordCredentials
      Console.WriteLine($"{oApp.DisplayName} - {oSecret.EndDateTime}")
    Next
  Next
End Function

It seems we tend to conflate the terminology here.

Hopefully that'll do the trick for you. If you actually need ServicePrincipals instead of Applications, I'm afraid I'm at a loss.

HTH

Neutrino-Sunset commented 1 year ago

Looks promising.

One question though. How are you able to use the DefaultAzureCrential class to authenticate with Grapg api? I thought the DefaultAzureCredential class used the Managed Identity associated with the Azure app/resource, and that Graph API permissions couldn't be associated with the Managed Identity.

InteXX commented 1 year ago

@Neutrino-Sunset

How are you able to use the DefaultAzureCrential class to authenticate

That's just my own shortcut for one-off dev work, prototypes and such. Since I run those in Debug, they pick up my identity from my current Visual Studio session (my login account). Of course in a production/release scenario I'd use something different, probably a ClientSecretCredential.

image

More info:

https://www.rahulpnath.com/blog/defaultazurecredential-from-azure-sdk/

ArthurMa1978 commented 1 year ago

@ArthurMa1978 Arthur Ma FTE

Thank you for your quick reply.

Pardon me, I didn't notice the namespace in the topic that I reported. Yes, that reference is indeed for the old SDK.

Nevertheless, I can assure you that I'm using the new version in my code. The type names are the same in this case, which is what threw me off a bit.

But in the end, the new documentation suffers from the same problem.

The problem is that there's no guidance on how to actually use the SDK. The few published sample applications are sharply limited in nature, and the official documentation provides no insight into its use—only member declarations and type hierarchies. That's a lot to wade through and not much to go on. A couple of lines of sample code per topic would be very helpful.

We're flying blind out here, and I'm sad to report that it's not going so well.

How can I use the new SDK to upload and install a third-party TLS certificate to an App Service? I should think this to be a fairly common scenario.

Thanks again.

We apologize for the low quality of the document. It is automatically created from the REST API specification. We will contact the service team to improve the documentation.

ArthurMa1978 commented 1 year ago

@ArthurMa1978 Arthur Ma FTE

What is the SDK equivalent of this REST API?

Unfortunately, the SDK is so poorly documented that—after two full days of digging—I finally have to ask.

This one

InteXX commented 1 year ago

@ArthurMa1978

Thank you for your reply.

I'd like to address the reason behind my earlier assessment, i.e. "the SDK is so poorly documented."

First, I'll refer to the rich bounty of SDK code samples that I stumbled upon completely by accident, samples that aren't linked to from any documentation that I've been able to find and that apparently are hidden from easy discovery.

For example, let's look at the Azure.ResourceManager.AppService namespace that you mentioned. The SDK documentation for this, unfortunately quite sparse in terms of how to actually use it, is here:

https://learn.microsoft.com/en-us/dotnet/api/azure.resourcemanager.appservice

Its corresponding (hidden) code samples are here:

https://github.com/Azure/azure-sdk-for-net/tree/main/sdk/websites/Azure.ResourceManager.AppService/samples

There's no reason that the documentation for each namespace can't link to its corresponding samples.

Let's go a step further. Review the documentation for this SDK method:

https://learn.microsoft.com/en-us/dotnet/api/azure.resourcemanager.appservice.appcertificatecollection.createorupdate

Note that the corresponding REST API is shown there, i.e.

/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/certificates/{name}

Unfortunately, however, the user is left to wander about aimlessly, trying to find the documentation for that particular REST API call. It's here:

https://learn.microsoft.com/en-us/rest/api/appservice/certificates/create-or-update

But when we load up that page, we also find that there's no link back to the SDK version of the call.

In other words, the REST API documentation doesn't link to the SDK documentation and the converse. Each exists in a silo and is therefore next to impossible for a frustrated developer to discover. And then for that poor chap to try to find the rich bounty of (hidden) SDK samples heretofore mentioned? It's enough to drive him silly.

What a waste of our valuable time that's caused by this unfortunate situation.

Further, the samples that actually ARE linked to from the main Azure developer page are woefully sparse in scope. I'll illustrate.

  1. First, go here: https://learn.microsoft.com/en-us/dotnet/azure/.
  2. Of the eight sections there, click the lower right one, Get Started - Azure SDK for .NET.
  3. In the TOC at the left, click the last child node of the Azure SDK for .NET topic node, SDK example.
  4. This takes us to Azure Identity, Resource Management, and Storage sample. Click Browse code.
  5. Note the markedly feeble sample code here. To the developer unaware of the hidden SDK samples, this is very discouraging, especially considering the sparse nature of the documentation itself.

In summary:

Thank you for considering this significant improvement to the Azure developer documentation.

ArthurMa1978 commented 1 year ago

@ArthurMa1978

Thank you for your reply.

I'd like to address the reason behind my earlier assessment, i.e. "the SDK is so poorly documented."

First, I'll refer to the rich bounty of SDK code samples that I stumbled upon completely by accident, samples that aren't linked to from any documentation that I've been able to find and that apparently are hidden from easy discovery.

For example, let's look at the Azure.ResourceManager.AppService namespace that you mentioned. The SDK documentation for this, unfortunately quite sparse in terms of how to actually use it, is here:

https://learn.microsoft.com/en-us/dotnet/api/azure.resourcemanager.appservice

Its corresponding (hidden) code samples are here:

https://github.com/Azure/azure-sdk-for-net/tree/main/sdk/websites/Azure.ResourceManager.AppService/samples

There's no reason that the documentation for each namespace can't link to its corresponding samples.

Let's go a step further. Review the documentation for this SDK method:

https://learn.microsoft.com/en-us/dotnet/api/azure.resourcemanager.appservice.appcertificatecollection.createorupdate

Note that the corresponding REST API is shown there, i.e.

/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/certificates/{name}

Unfortunately, however, the user is left to wander about aimlessly, trying to find the documentation for that particular REST API call. It's here:

https://learn.microsoft.com/en-us/rest/api/appservice/certificates/create-or-update

But when we load up that page, we also find that there's no link back to the SDK version of the call.

In other words, the REST API documentation doesn't link to the SDK documentation and the converse. Each exists in a silo and is therefore next to impossible for a frustrated developer to discover. And then for that poor chap to try to find the rich bounty of (hidden) SDK samples heretofore mentioned? It's enough to drive him silly.

What a waste of our valuable time that's caused by this unfortunate situation.

Further, the samples that actually ARE linked to from the main Azure developer page are woefully sparse in scope. I'll illustrate.

  1. First, go here: https://learn.microsoft.com/en-us/dotnet/azure/.
  2. Of the eight sections there, click the lower right one, Get Started - Azure SDK for .NET.
  3. In the TOC at the left, click the last child node of the Azure SDK for .NET topic node, SDK example.
  4. This takes us to Azure Identity, Resource Management, and Storage sample. Click Browse code.
  5. Note the markedly feeble sample code here. To the developer unaware of the hidden SDK samples, this is very discouraging, especially considering the sparse nature of the documentation itself.

In summary:

  • The REST API documentation for a given call should link to the SDK equivalent.
  • The SDK documentation for a given call should link to the REST API equivalent.
  • The SDK documentation for each namespace should link to its corresponding, currently-hidden SDK samples.

Thank you for considering this significant improvement to the Azure developer documentation.

Thank you for your valuable feedback, @InteXX! I agree with your points. We are collaborating with multiple teams to enhance the document. This is a massive project that may take a while, but it is very important for all developers and we are committed to investing in it.

InteXX commented 1 year ago

@ArthurMa1978

Thank you for your kind reply. I understand that something like this can take some time.

I'm pleased to learn that you're giving it due attention.

InteXX commented 8 months ago

ArthurMa1978 closed this as completed 9 hours ago

@ArthurMa1978

I'm not sure I follow you here... can you assist?

I'm not seeing any of the suggested improvements to the developer documentation; in fact, it appears to not have changed at all.

Could this mean that the team decided not to undertake the improvements? Or simply that they're completed but not published yet?

ArthurMa1978 commented 8 months ago

Sorry, I closed this by mistake, reopen.

InteXX commented 8 months ago

Sorry, I closed this by mistake

Ah... that's a third possibility I hadn't considered 😉