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.24k stars 4.58k forks source link

Cross RP dependency - Orphaned models and operations between Network and Compute need dependency resolved #28185

Closed m-nash closed 1 year ago

m-nash commented 2 years ago

Problem • There are APIs defined under different provider, like this. • Those API resources are orphans, so that the hierarchy API cannot be generated. But the extension API are generated. o For example, this API is orphan because VirtualMachineScaleSet and VirtualMachine are not defined in “network”. o I haven’t tried if APIs under different provider are not orphans. I guess they can be generated. If not, that is another issue.

Solution Packaging • We cannot generate the API in the RP which should own the provider name (e.g. “compute”), because API Version could be different. • We can generate the API in where it’s defined but choose different packaging strategy. o We can just generate the API in “network”, and then mark “network” depending on “compute”.  Prons: simple because the API is defined in “network”  Crons: “network” has to depend on “compute” • There is a potential risk that two RPs have cross dependency (e.g. both have API defined under other’s provider name) o Or we can generate the API in a separate package, and then mark that package pending on both “network” and “compute”.  Prons: • “network” do not depend on “compute” • Eliminate the cross dependency  Crons: • Make the dependency more complex • People might have difficult to find those API (especially for track1 users who get used to)

How to generate the codes Take "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/microsoft.Compute/virtualMachineScaleSets/{virtualMachineScaleSetName}/virtualMachines/{virtualmachineIndex}/networkInterfaces" as example. • Create a new directive “virtual-resources” o Each entry is a pair of path and resource name. For example, virtual machine scale set should have:  Path: “/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/microsoft.Compute/virtualMachineScaleSets”  Name: “VirtualMachineSacleSet” • For generator: o It will assume a virtual resource exists, so that the leaf resources can be connected to the hierarchy (e.g., “networkInterfaces”) o It will only generate codes of a virtual resource if its child resource is non-virtual (e.g., “VirtualMachineScaleSet” will not be generated, but “VirtualMachine” will be generated)  It will only generate codes to get child resources (e.g., “VirtualMachine.GetNetworkInterfaces”)

azure-sdk commented 2 years ago

Label prediction was below confidence level 0.6 for Model:ServiceLabels: 'Compute:0.26110464,Storage:0.11031185,Cognitive - Computer Vision:0.051708583'

m-nash commented 2 years ago

I think the direction we want to go here is move the common items from Compute that Network needs to add extensions to into a new package called Azure.ResourceManager.Compute.Common. Both Azure.ResourceManager.Compute and Azure.ResourceManager.Network will depend on this new package.

m-nash commented 2 years ago

Lets do some diligence on trying to find all cases that are similar to this before we finalize to make sure there isn't any underlying patterns that we might want to do differently.

ArcturusZhang commented 2 years ago

The following is the result of a full scan on the existing swaggers. Every section here is a resource in one RP, and the values listing in the section is the path of the operations that are extending it in another RP.

NOTE: This list does not include the case that two different RPs sharing the same namespace (like dnsresolver and network, they both have namespace Microsoft.Network).

VirtualMachine (RP: compute, path: /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachines/{vmName})

VirtualMachineScaleSet (RP: compute, path: /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachineScaleSets/{vmssName})

VirtualMachineScaleSetVm (RP: compute, path: /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachineScaleSets/{virtualMachineScaleSetName}/virtualMachines/{virtualmachineIndex})

CloudService (RP: compute, path: /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/cloudServices/{cloudServiceName})

CloudServiceRoleInstance (RP: compute, path: /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/cloudServices/{cloudServiceName}/roleInstances/{roleInstanceName})

BillingAccount (RP: billing, path: /providers/Microsoft.Billing/billingAccounts/{billingAccountName})

BillingCustomer (RP: billing, path: /providers/Microsoft.Billing/billingAccounts/{billingAccountName}/customers/{customerName})

BillingProfile (RP: billing, path: /providers/Microsoft.Billing/billingAccounts/{billingAccountName}/billingProfiles/{billingProfileName})

Invoice (RP: billing, path: /providers/Microsoft.Billing/billingAccounts/{billingAccountName}/billingProfiles/{billingProfileName}/invoices/{invoiceName})

InvoiceSection (RP: billing, path: /providers/Microsoft.Billing/billingAccounts/{billingAccountName}/invoiceSections/{invoiceSectionName})

SubscriptionBillingPeriod (RP: billing, path: /subscriptions/{subscriptionId}/providers/Microsoft.Billing/billingPeriods/{billingPeriodName})

Department (RP: billing, path: /providers/Microsoft.Billing/billingAccounts/{billingAccountName}/departments/{departmentName})

EnrollmentAccount (RP: billing, path: /providers/Microsoft.Billing/billingAccounts/{billingAccountName}/enrollmentAccounts/{enrollmentAccountName})

EnrollmentAccount (RP: billing, path: /providers/Microsoft.Billing/enrollmentAccounts/{name})

Subnet (RP: billing, path: /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworks/{virtualNetworkName}/subnets/{subnetName})

HybirdMachine (RP: hybridcompute, path: /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/machines/{machineName})

ReservationOrder (RP: reservation, path: /providers/Microsoft.Capacity/reservationOrders/{reservationOrderId})

Reservation (RP: reservation, path: /providers/Microsoft.Capacity/reservationOrders/{reservationOrderId}/reservations/{reservationId})

perationalInsightWorkspace (RP: operationalinsights, path: /subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName})

SqlServer (RP: sql, path: /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Sql/servers/{serverName})

SqlManagedInstance (RP: sql, path: /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Sql/managedInstances/{managedInstanceName})

SqlVirtualMachine (RP: sqlvirtualmachine, path: /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.SqlVirtualMachine/sqlVirtualMachines/{sqlVirtualMachineName})

No Resource has this path: /providers/Microsoft.Billing/billingAccounts/{billingAccountId}/providers/Microsoft.Billing/billingPeriods/{billingPeriodName}

No Resource has this path: /providers/Microsoft.Billing/departments/{departmentId}/providers/Microsoft.Billing/billingPeriods/{billingPeriodName}

No Resource has this path: /providers/Microsoft.Billing/enrollmentAccounts/{enrollmentAccountId}/providers/Microsoft.Billing/billingPeriods/{billingPeriodName}

No Resource has this path: /providers/Microsoft.Management/managementGroups/{managementGroupId}/providers/Microsoft.Billing/billingPeriods/{billingPeriodName}

No Resource has this path: /providers/Microsoft.CostManagement/billingAccounts/{billingAccountId}

No Resource has this path: /providers/Microsoft.Billing/billingAccounts/{billingAccountId}/enrollmentAccounts/{enrollmentAccountId}/providers/Microsoft.Billing/billingPeriods/{billingPeriodName}

No Resource has this path: /providers/Microsoft.Billing/departments/{departmentId}

No Resource has this path: /providers/Microsoft.Billing/billingAccounts/{billingAccountId}/billingPeriods/{billingPeriodName}

No Resource has this path: /providers/Microsoft.Billing/billingAccounts/{billingAccountId}/departments/{departmentId}/providers/Microsoft.Billing/billingPeriods/{billingPeriodName}

ArcturusZhang commented 2 years ago

A brief version of the summary: 22 Resources have extension methods from other RPs spread across 7 different RPs

Those Resources live in 8 different RPs

m-nash commented 2 years ago

Our path forward will be to follow the prototype in https://github.com/Azure/azure-sdk-for-net/pull/28400. In general we will create a new class called [Entity][RP]Resource that inherits from ArmResource and adds the new methods. This class will exist in the project that is extending the new resource.

For the example of network extended VirtualMachineScaleSetResource the new class will be called VirtualMachineScaleSetNetworkResource. This allows for unique names in the case that multiple RPs extend the same type.

Given this can be done post GA removing this as a requirement to release Compute and Network. The initial GA version of Network may not contain these methods.