diff --git a/.chronus/changes/azhang_armReorg-2024-3-29-17-13-46.md b/.chronus/changes/azhang_armReorg-2024-3-29-17-13-46.md new file mode 100644 index 0000000000..62e4b30602 --- /dev/null +++ b/.chronus/changes/azhang_armReorg-2024-3-29-17-13-46.md @@ -0,0 +1,20 @@ +--- +changeKind: deprecation +packages: + - "@azure-tools/typespec-azure-resource-manager" +--- + +Renaming internal TypeSpec ARM foundation model names to be consistent with ARM common-type definitions. +However, these are `Azure.Resource.Manager.Foundations` models that would not normally be used directly in service specs. + +- Deprecate `Foundations.ArmResource`. `Foundations.Resource` should be used instead. + +- Deprecate `Foundations.ResourceSkuType`. `Foundations.Sku` should be used instead. + +- Deprecate `Foundations.ResourcePlanType`. `Foundations.Plan` should be used instead. + +- Deprecate `Foundations.TrackedResourceBase`. `Foundations.TrackedResource` should be used instead. + +- Deprecate `Foundations.ProxyResourceBase`. `Foundations.ProxyResource` should be used instead. + +- Deprecate `Foundations.ExtensionResourceBase`. `Foundations.ExtensionResource` should be used instead. diff --git a/docs/libraries/azure-resource-manager/reference/data-types.md b/docs/libraries/azure-resource-manager/reference/data-types.md index e92e8764f6..4ff9d9907b 100644 --- a/docs/libraries/azure-resource-manager/reference/data-types.md +++ b/docs/libraries/azure-resource-manager/reference/data-types.md @@ -513,9 +513,9 @@ model Employee is TrackedResource { #### Properties -| Name | Type | Description | -| ---------------- | ---------------------------------------------------------------------------------------- | ----------- | -| extendedLocation | [`ExtendedLocation`](./data-types.md#Azure.ResourceManager.Foundations.ExtendedLocation) | | +| Name | Type | Description | +| ----------------- | ---------------------------------------------------------------------------------------- | ----------- | +| extendedLocation? | [`ExtendedLocation`](./data-types.md#Azure.ResourceManager.Foundations.ExtendedLocation) | | ### `ExtensionResource` {#Azure.ResourceManager.ExtensionResource} @@ -1039,9 +1039,9 @@ model Foo is TrackedResource { #### Properties -| Name | Type | Description | -| ----- | ---------------------------------------------------------------------------------------- | ----------------------------- | -| plan? | [`ResourcePlanType`](./data-types.md#Azure.ResourceManager.Foundations.ResourcePlanType) | Details of the resource plan. | +| Name | Type | Description | +| ----- | ---------------------------------------------------------------- | ----------------------------- | +| plan? | [`Plan`](./data-types.md#Azure.ResourceManager.Foundations.Plan) | Details of the resource plan. | ### `ResourceSkuProperty` {#Azure.ResourceManager.ResourceSkuProperty} @@ -1063,9 +1063,9 @@ model Foo is TrackedResource { #### Properties -| Name | Type | Description | -| ---- | -------------------------------------------------------------------------------------- | ------------------------------------------------------- | -| sku? | [`ResourceSkuType`](./data-types.md#Azure.ResourceManager.Foundations.ResourceSkuType) | The SKU (Stock Keeping Unit) assigned to this resource. | +| Name | Type | Description | +| ---- | -------------------------------------------------------------- | ------------------------------------------------------- | +| sku? | [`Sku`](./data-types.md#Azure.ResourceManager.Foundations.Sku) | The SKU (Stock Keeping Unit) assigned to this resource. | ### `ResourceUriParameter` {#Azure.ResourceManager.ResourceUriParameter} @@ -1220,50 +1220,35 @@ enum Azure.ResourceManager.CommonTypes.Versions ## Azure.ResourceManager.Foundations -### `ArmResource` {#Azure.ResourceManager.Foundations.ArmResource} - -Base model that defines common properties for all Azure Resource Manager resources. - -```typespec -model Azure.ResourceManager.Foundations.ArmResource -``` - -#### Properties - -| Name | Type | Description | -| ----------- | ---------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| id | `string` | Fully qualified resource ID for the resource. Ex - /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName} | -| name | `string` | The name of the resource | -| type | `string` | The type of the resource. E.g. "Microsoft.Compute/virtualMachines" or "Microsoft.Storage/storageAccounts" | -| systemData? | [`SystemData`](./data-types.md#Azure.ResourceManager.Foundations.SystemData) | Azure Resource Manager metadata containing createdBy and modifiedBy information. | +### `ArmTagsProperty` {#Azure.ResourceManager.Foundations.ArmTagsProperty} -### `ArmResourceBase` {#Azure.ResourceManager.Foundations.ArmResourceBase} +Standard type definition for Azure Resource Manager Tags property. -Base class used for type definitions +It is included in the TrackedResource template definition. ```typespec -model Azure.ResourceManager.Foundations.ArmResourceBase +model Azure.ResourceManager.Foundations.ArmTagsProperty ``` #### Properties -None - -### `ArmTagsProperty` {#Azure.ResourceManager.Foundations.ArmTagsProperty} +| Name | Type | Description | +| ----- | ---------------- | -------------- | +| tags? | `Record` | Resource tags. | -Standard type definition for Azure Resource Manager Tags property. +### `AzureEntityResource` {#Azure.ResourceManager.Foundations.AzureEntityResource} -It is included in the TrackedResource template definition. +The resource model definition for an Azure Resource Manager resource with an etag. ```typespec -model Azure.ResourceManager.Foundations.ArmTagsProperty +model Azure.ResourceManager.Foundations.AzureEntityResource ``` #### Properties -| Name | Type | Description | -| ----- | ---------------- | -------------- | -| tags? | `Record` | Resource tags. | +| Name | Type | Description | +| ---- | -------- | -------------- | +| etag | `string` | Resource Etag. | ### `CheckNameAvailabilityRequest` {#Azure.ResourceManager.Foundations.CheckNameAvailabilityRequest} @@ -1383,12 +1368,12 @@ model Azure.ResourceManager.Foundations.ExtensionBaseParameters | apiVersion | `string` | The API version to use for this operation. | | resourceUri | `string` | The fully qualified Azure Resource manager identifier of the resource. | -### `ExtensionResourceBase` {#Azure.ResourceManager.Foundations.ExtensionResourceBase} +### `ExtensionResource` {#Azure.ResourceManager.Foundations.ExtensionResource} The base extension resource. ```typespec -model Azure.ResourceManager.Foundations.ExtensionResourceBase +model Azure.ResourceManager.Foundations.ExtensionResource ``` #### Properties @@ -1558,12 +1543,30 @@ model Azure.ResourceManager.Foundations.OperationStatusResult | operations | `ResourceManager.Foundations.OperationStatusResult[]` | The operations list. | | error? | [`ErrorDetail`](./data-types.md#Azure.ResourceManager.Foundations.ErrorDetail) | If present, details of the operation error. | -### `ProxyResourceBase` {#Azure.ResourceManager.Foundations.ProxyResourceBase} +### `Plan` {#Azure.ResourceManager.Foundations.Plan} + +Details of the resource plan. + +```typespec +model Azure.ResourceManager.Foundations.Plan +``` + +#### Properties + +| Name | Type | Description | +| -------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | +| name | `string` | A user defined name of the 3rd Party Artifact that is being procured. | +| publisher | `string` | The publisher of the 3rd Party Artifact that is being bought. E.g. NewRelic | +| product | `string` | The 3rd Party artifact that is being procured. E.g. NewRelic. Product maps to the OfferID specified for the artifact at the time of Data Market onboarding. | +| promotionCode? | `string` | A publisher provided promotion code as provisioned in Data Market for the said product/artifact. | +| version? | `string` | The version of the desired product/artifact. | + +### `ProxyResource` {#Azure.ResourceManager.Foundations.ProxyResource} The base proxy resource. ```typespec -model Azure.ResourceManager.Foundations.ProxyResourceBase +model Azure.ResourceManager.Foundations.ProxyResource ``` #### Properties @@ -1591,6 +1594,23 @@ model Azure.ResourceManager.Foundations.ProxyResourceUpdateModel` | | +### `Resource` {#Azure.ResourceManager.Foundations.Resource} + +Base model that defines common properties for all Azure Resource Manager resources. + +```typespec +model Azure.ResourceManager.Foundations.Resource +``` + +#### Properties + +| Name | Type | Description | +| ----------- | ---------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| id? | `string` | Fully qualified resource ID for the resource. Ex - /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName} | +| name? | `string` | The name of the resource | +| type? | `string` | The type of the resource. E.g. "Microsoft.Compute/virtualMachines" or "Microsoft.Storage/storageAccounts" | +| systemData? | [`SystemData`](./data-types.md#Azure.ResourceManager.Foundations.SystemData) | Azure Resource Manager metadata containing createdBy and modifiedBy information. | + ### `ResourceGroupBaseParameters` {#Azure.ResourceManager.Foundations.ResourceGroupBaseParameters} The static parameters for a resource-group based resource @@ -1632,42 +1652,6 @@ model Azure.ResourceManager.Foundations.ResourceGroupScope | resourceUri | `string` | The fully qualified Azure Resource manager identifier of the resource. | | provider | `"Microsoft.ThisWillBeReplaced"` | The provider namespace for the resource. | -### `ResourcePlanType` {#Azure.ResourceManager.Foundations.ResourcePlanType} - -Details of the resource plan. - -```typespec -model Azure.ResourceManager.Foundations.ResourcePlanType -``` - -#### Properties - -| Name | Type | Description | -| -------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | -| name | `string` | A user defined name of the 3rd Party Artifact that is being procured. | -| publisher | `string` | The publisher of the 3rd Party Artifact that is being bought. E.g. NewRelic | -| product | `string` | The 3rd Party artifact that is being procured. E.g. NewRelic. Product maps to the OfferID specified for the artifact at the time of Data Market onboarding. | -| promotionCode? | `string` | A publisher provided promotion code as provisioned in Data Market for the said product/artifact. | -| version? | `string` | The version of the desired product/artifact. | - -### `ResourceSkuType` {#Azure.ResourceManager.Foundations.ResourceSkuType} - -The SKU (Stock Keeping Unit) assigned to this resource. - -```typespec -model Azure.ResourceManager.Foundations.ResourceSkuType -``` - -#### Properties - -| Name | Type | Description | -| --------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | -| name | `string` | The name of the SKU, usually a combination of letters and numbers, for example, 'P3' | -| tier? | [`SkuTier`](./data-types.md#Azure.ResourceManager.Foundations.SkuTier) | This field is required to be implemented by the Resource Provider if the service has more than one tier, but is not required on a PUT. | -| size? | `string` | The SKU size. When the name field is the combination of tier and some other value, this would be the standalone code. | -| family? | `string` | If the service has different generations of hardware, for the same SKU, then that can be captured here. | -| capacity? | `int32` | If the SKU supports scale out/in then the capacity integer should be included. If scale out/in is not possible for the resource this may be omitted. | - ### `ResourceUpdateModel` {#Azure.ResourceManager.Foundations.ResourceUpdateModel} Defines a model type used to create named resource update models @@ -1710,6 +1694,24 @@ model Azure.ResourceManager.Foundations.ResourceUpdateModelProperties | apiVersion | `string` | The API version to use for this operation. | | provider | `"Microsoft.ThisWillBeReplaced"` | The provider namespace for the resource. | -### `TrackedResourceBase` {#Azure.ResourceManager.Foundations.TrackedResourceBase} +### `TrackedResource` {#Azure.ResourceManager.Foundations.TrackedResource} The base tracked resource. ```typespec -model Azure.ResourceManager.Foundations.TrackedResourceBase +model Azure.ResourceManager.Foundations.TrackedResource ``` #### Properties diff --git a/docs/libraries/azure-resource-manager/reference/index.mdx b/docs/libraries/azure-resource-manager/reference/index.mdx index 462c793a86..51360a7a56 100644 --- a/docs/libraries/azure-resource-manager/reference/index.mdx +++ b/docs/libraries/azure-resource-manager/reference/index.mdx @@ -190,9 +190,8 @@ npm install --save-peer @azure-tools/typespec-azure-resource-manager ### Models -- [`ArmResource`](./data-types.md#Azure.ResourceManager.Foundations.ArmResource) -- [`ArmResourceBase`](./data-types.md#Azure.ResourceManager.Foundations.ArmResourceBase) - [`ArmTagsProperty`](./data-types.md#Azure.ResourceManager.Foundations.ArmTagsProperty) +- [`AzureEntityResource`](./data-types.md#Azure.ResourceManager.Foundations.AzureEntityResource) - [`CheckNameAvailabilityRequest`](./data-types.md#Azure.ResourceManager.Foundations.CheckNameAvailabilityRequest) - [`CheckNameAvailabilityResponse`](./data-types.md#Azure.ResourceManager.Foundations.CheckNameAvailabilityResponse) - [`DefaultBaseParameters`](./data-types.md#Azure.ResourceManager.Foundations.DefaultBaseParameters) @@ -200,7 +199,7 @@ npm install --save-peer @azure-tools/typespec-azure-resource-manager - [`ErrorDetail`](./data-types.md#Azure.ResourceManager.Foundations.ErrorDetail) - [`ExtendedLocation`](./data-types.md#Azure.ResourceManager.Foundations.ExtendedLocation) - [`ExtensionBaseParameters`](./data-types.md#Azure.ResourceManager.Foundations.ExtensionBaseParameters) -- [`ExtensionResourceBase`](./data-types.md#Azure.ResourceManager.Foundations.ExtensionResourceBase) +- [`ExtensionResource`](./data-types.md#Azure.ResourceManager.Foundations.ExtensionResource) - [`ExtensionScope`](./data-types.md#Azure.ResourceManager.Foundations.ExtensionScope) - [`LocationBaseParameters`](./data-types.md#Azure.ResourceManager.Foundations.LocationBaseParameters) - [`LocationScope`](./data-types.md#Azure.ResourceManager.Foundations.LocationScope) @@ -210,14 +209,15 @@ npm install --save-peer @azure-tools/typespec-azure-resource-manager - [`OperationIdParameter`](./data-types.md#Azure.ResourceManager.Foundations.OperationIdParameter) - [`OperationListResult`](./data-types.md#Azure.ResourceManager.Foundations.OperationListResult) - [`OperationStatusResult`](./data-types.md#Azure.ResourceManager.Foundations.OperationStatusResult) -- [`ProxyResourceBase`](./data-types.md#Azure.ResourceManager.Foundations.ProxyResourceBase) +- [`Plan`](./data-types.md#Azure.ResourceManager.Foundations.Plan) +- [`ProxyResource`](./data-types.md#Azure.ResourceManager.Foundations.ProxyResource) - [`ProxyResourceUpdateModel`](./data-types.md#Azure.ResourceManager.Foundations.ProxyResourceUpdateModel) +- [`Resource`](./data-types.md#Azure.ResourceManager.Foundations.Resource) - [`ResourceGroupBaseParameters`](./data-types.md#Azure.ResourceManager.Foundations.ResourceGroupBaseParameters) - [`ResourceGroupScope`](./data-types.md#Azure.ResourceManager.Foundations.ResourceGroupScope) -- [`ResourcePlanType`](./data-types.md#Azure.ResourceManager.Foundations.ResourcePlanType) -- [`ResourceSkuType`](./data-types.md#Azure.ResourceManager.Foundations.ResourceSkuType) - [`ResourceUpdateModel`](./data-types.md#Azure.ResourceManager.Foundations.ResourceUpdateModel) - [`ResourceUpdateModelProperties`](./data-types.md#Azure.ResourceManager.Foundations.ResourceUpdateModelProperties) +- [`Sku`](./data-types.md#Azure.ResourceManager.Foundations.Sku) - [`SubscriptionBaseParameters`](./data-types.md#Azure.ResourceManager.Foundations.SubscriptionBaseParameters) - [`SubscriptionScope`](./data-types.md#Azure.ResourceManager.Foundations.SubscriptionScope) - [`SystemAssignedServiceIdentity`](./data-types.md#Azure.ResourceManager.Foundations.SystemAssignedServiceIdentity) @@ -225,6 +225,6 @@ npm install --save-peer @azure-tools/typespec-azure-resource-manager - [`TagsUpdateModel`](./data-types.md#Azure.ResourceManager.Foundations.TagsUpdateModel) - [`TenantBaseParameters`](./data-types.md#Azure.ResourceManager.Foundations.TenantBaseParameters) - [`TenantScope`](./data-types.md#Azure.ResourceManager.Foundations.TenantScope) -- [`TrackedResourceBase`](./data-types.md#Azure.ResourceManager.Foundations.TrackedResourceBase) +- [`TrackedResource`](./data-types.md#Azure.ResourceManager.Foundations.TrackedResource) - [`UserAssignedIdentities`](./data-types.md#Azure.ResourceManager.Foundations.UserAssignedIdentities) - [`UserAssignedIdentity`](./data-types.md#Azure.ResourceManager.Foundations.UserAssignedIdentity) diff --git a/packages/samples/specs/resource-manager/liftr.confluent/confluent.tsp b/packages/samples/specs/resource-manager/liftr.confluent/confluent.tsp index 0c636bbcd8..35eba3b08b 100644 --- a/packages/samples/specs/resource-manager/liftr.confluent/confluent.tsp +++ b/packages/samples/specs/resource-manager/liftr.confluent/confluent.tsp @@ -8,7 +8,6 @@ using TypeSpec.Http; using TypeSpec.Rest; using TypeSpec.Versioning; using Azure.ResourceManager; -using Azure.ResourceManager.Foundations; using Autorest; @armProviderNamespace @@ -164,7 +163,7 @@ interface MarketplaceAgreements extends ResourceListBySubscription, + ...Foundations.SubscriptionScope, ...KeysOf, @doc("The agreement details.") diff --git a/packages/typespec-azure-resource-manager/lib/arm.foundations.tsp b/packages/typespec-azure-resource-manager/lib/arm.foundations.tsp index 34194e769c..47fdbf802f 100644 --- a/packages/typespec-azure-resource-manager/lib/arm.foundations.tsp +++ b/packages/typespec-azure-resource-manager/lib/arm.foundations.tsp @@ -30,14 +30,14 @@ enum ResourceHome { * * @template Resource The type of the resource. */ -alias BaseParameters = DefaultBaseParameters; +alias BaseParameters = DefaultBaseParameters; /** * Base parameters for a resource. * @template Resource The type of the resource. */ @resourceBaseParametersOf(Resource) -model DefaultBaseParameters { +model DefaultBaseParameters { ...ApiVersionParameter; // unless tenant or extension @@ -97,7 +97,7 @@ model ExtensionBaseParameters is TenantBaseParameters { @doc("The updatable properties of the {name}.", Resource) @friendlyName("{name}UpdateProperties", Resource) model ResourceUpdateModelProperties< - Resource extends ArmResource, + Resource extends Foundations.Resource, Properties extends TypeSpec.Reflection.Model > is OptionalProperties>; @@ -111,7 +111,7 @@ model ResourceUpdateModelProperties< @friendlyName("{name}Update", Resource) @omitIfEmpty("properties") model ResourceUpdateModel< - Resource extends ArmResource, + Resource extends Foundations.Resource, Properties extends TypeSpec.Reflection.Model > is OptionalProperties>> { @extension("x-ms-client-flatten", true) @@ -124,47 +124,48 @@ model ResourceUpdateModel< */ @doc("The type used for updating tags in {name} resources.", Resource) @friendlyName("{name}TagsUpdate", Resource) -model TagsUpdateModel { +model TagsUpdateModel { ...ArmTagsProperty; } // Tenant resource operation definitions -alias TenantParentScope = TenantScope; +alias TenantParentScope = TenantScope; /** * Parameter model for listing a resource at the tenant scope * @template Resource The type of the resource. */ -model TenantScope +model TenantScope is ResourceParentParameters; /** * Parameter model for listing a resource at the subscription scope * @template Resource The type of the resource. */ -model SubscriptionScope +model SubscriptionScope is ResourceParentParameters; /** * Parameter model for listing a resource at the location scope * @template Resource The type of the resource. */ -model LocationScope +model LocationScope is ResourceParentParameters; /** * Parameter model for listing an extension resource * @template Resource The type of the resource. */ -model ExtensionScope +model ExtensionScope is ResourceParentParameters; /** * Parameter model for listing a resource at the resource group scope * @template Resource The type of the resource. */ -model ResourceGroupScope is ResourceParentParameters; +model ResourceGroupScope + is ResourceParentParameters; /** * The type used for update operations of the resource. @@ -174,7 +175,7 @@ model ResourceGroupScope is ResourceParentParamete @doc("The type used for update operations of the {name}.", Resource) @friendlyName("{name}Update", Resource) model ProxyResourceUpdateModel< - Resource extends ArmResource, + Resource extends Foundations.Resource, Properties extends TypeSpec.Reflection.Model > { @extension("x-ms-client-flatten", true) diff --git a/packages/typespec-azure-resource-manager/lib/arm.tsp b/packages/typespec-azure-resource-manager/lib/arm.tsp index c45950c8cc..69ad03c247 100644 --- a/packages/typespec-azure-resource-manager/lib/arm.tsp +++ b/packages/typespec-azure-resource-manager/lib/arm.tsp @@ -8,6 +8,7 @@ import "@azure-tools/typespec-azure-core"; import "./arm.foundations.tsp"; import "./common-types/common-types.tsp"; +import "./common-types/backcompat.tsp"; import "./common-types/types.tsp"; import "./common-types/managed-identity.tsp"; import "./common-types/private-links.tsp"; diff --git a/packages/typespec-azure-resource-manager/lib/common-types/backcompat.tsp b/packages/typespec-azure-resource-manager/lib/common-types/backcompat.tsp new file mode 100644 index 0000000000..bca365485f --- /dev/null +++ b/packages/typespec-azure-resource-manager/lib/common-types/backcompat.tsp @@ -0,0 +1,19 @@ +namespace Azure.ResourceManager.Foundations; + +#deprecated "Please use Foundations.Resource instead of Foundations.ArmResource" +alias ArmResource = Resource; + +#deprecated "Please use Foundations.TrackedResource instead of Foundations.TrackedResourceBase" +alias TrackedResourceBase = TrackedResource; + +#deprecated "Please use Foundations.ProxyResource instead of Foundations.ProxyResourceBase" +alias ProxyResourceBase = ProxyResource; + +#deprecated "Please use Foundations.ProxyResource instead of Foundations.ExtensionResourceBase" +alias ExtensionResourceBase = ExtensionResource; + +#deprecated "Please use Foundations.Sku instead of Foundations.ResourceSkuType" +alias ResourceSkuType = Sku; + +#deprecated "Please use Foundations.Plan instead of Foundations.ResourcePlanType" +alias ResourcePlanType = Plan; diff --git a/packages/typespec-azure-resource-manager/lib/common-types/private-links.tsp b/packages/typespec-azure-resource-manager/lib/common-types/private-links.tsp index 1bf17a3007..b15d734e6d 100644 --- a/packages/typespec-azure-resource-manager/lib/common-types/private-links.tsp +++ b/packages/typespec-azure-resource-manager/lib/common-types/private-links.tsp @@ -36,7 +36,7 @@ model PrivateEndpoint { } /** The private endpoint connection resource */ -model PrivateEndpointConnection extends Azure.ResourceManager.Foundations.ProxyResourceBase { +model PrivateEndpointConnection extends Azure.ResourceManager.Foundations.ProxyResource { /** The private endpoint connection properties */ properties?: PrivateEndpointConnectionProperties; } @@ -120,7 +120,7 @@ union PrivateEndpointServiceConnectionStatus { string, } -model PrivateLinkResource extends Azure.ResourceManager.Foundations.ProxyResourceBase { +model PrivateLinkResource extends Azure.ResourceManager.Foundations.ProxyResource { /** Properties of the private link resource. */ properties?: PrivateLinkResourceProperties; } diff --git a/packages/typespec-azure-resource-manager/lib/common-types/types.tsp b/packages/typespec-azure-resource-manager/lib/common-types/types.tsp index 7960176322..fb02a7f72e 100644 --- a/packages/typespec-azure-resource-manager/lib/common-types/types.tsp +++ b/packages/typespec-azure-resource-manager/lib/common-types/types.tsp @@ -1,34 +1,42 @@ using TypeSpec.Http; using TypeSpec.OpenAPI; +using Azure.Core; using Azure.ResourceManager.Private; namespace Azure.ResourceManager.Foundations; -/** Base class used for type definitions */ -model ArmResourceBase {} - /** * Base model that defines common properties for all Azure Resource Manager resources. */ @doc("Common properties for all Azure Resource Manager resources.") -model ArmResource extends ArmResourceBase { +model Resource { @doc("Fully qualified resource ID for the resource. Ex - /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}") @visibility("read") - id: string; + id?: string; @doc("The name of the resource") @visibility("read") - name: string; + name?: string; @doc("The type of the resource. E.g. \"Microsoft.Compute/virtualMachines\" or \"Microsoft.Storage/storageAccounts\"") @visibility("read") - type: string; + type?: string; @doc("Azure Resource Manager metadata containing createdBy and modifiedBy information.") @visibility("read") systemData?: SystemData; } +/** The resource model definition for an Azure Resource Manager resource with an etag. */ +@armCommonDefinition("TrackedResource", Azure.ResourceManager.CommonTypes.Versions.v3) +@armCommonDefinition("TrackedResource", Azure.ResourceManager.CommonTypes.Versions.v4) +@armCommonDefinition("TrackedResource", Azure.ResourceManager.CommonTypes.Versions.v5) +model AzureEntityResource extends Resource { + /** Resource Etag. */ + @visibility("read") + etag: string; +} + /** * Standard type definition for Azure Resource Manager Tags property. * @@ -46,8 +54,8 @@ model ArmTagsProperty { @armCommonDefinition("TrackedResource", Azure.ResourceManager.CommonTypes.Versions.v3) @armCommonDefinition("TrackedResource", Azure.ResourceManager.CommonTypes.Versions.v4) @armCommonDefinition("TrackedResource", Azure.ResourceManager.CommonTypes.Versions.v5) -@doc("The resource model definition for an Azure Resource Manager tracked top level resource") -model TrackedResourceBase extends ArmResource { +@doc("The resource model definition for an Azure Resource Manager tracked top level resource which has 'tags' and a 'location'") +model TrackedResource extends Resource { @doc("The geo-location where the resource lives") @visibility("read", "create") location: string; @@ -62,7 +70,7 @@ model TrackedResourceBase extends ArmResource { @armCommonDefinition("ProxyResource", Azure.ResourceManager.CommonTypes.Versions.v3) @armCommonDefinition("ProxyResource", Azure.ResourceManager.CommonTypes.Versions.v4) @armCommonDefinition("ProxyResource", Azure.ResourceManager.CommonTypes.Versions.v5) -model ProxyResourceBase extends ArmResource {} +model ProxyResource extends Resource {} /** * The base extension resource. @@ -72,7 +80,7 @@ model ProxyResourceBase extends ArmResource {} @armCommonDefinition("ProxyResource", Azure.ResourceManager.CommonTypes.Versions.v3) @armCommonDefinition("ProxyResource", Azure.ResourceManager.CommonTypes.Versions.v4) @armCommonDefinition("ProxyResource", Azure.ResourceManager.CommonTypes.Versions.v5) -model ExtensionResourceBase extends ArmResource {} +model ExtensionResource extends Resource {} /** * The SKU (Stock Keeping Unit) assigned to this resource. @@ -81,7 +89,7 @@ model ExtensionResourceBase extends ArmResource {} @armCommonDefinition("Sku", Azure.ResourceManager.CommonTypes.Versions.v3) @armCommonDefinition("Sku", Azure.ResourceManager.CommonTypes.Versions.v4) @armCommonDefinition("Sku", Azure.ResourceManager.CommonTypes.Versions.v5) -model ResourceSkuType { +model Sku { @doc("The name of the SKU, usually a combination of letters and numbers, for example, 'P3'") name: string; @@ -379,7 +387,7 @@ union createdByType { @armCommonDefinition("Plan", Azure.ResourceManager.CommonTypes.Versions.v3) @armCommonDefinition("Plan", Azure.ResourceManager.CommonTypes.Versions.v4) @armCommonDefinition("Plan", Azure.ResourceManager.CommonTypes.Versions.v5) -model ResourcePlanType { +model Plan { @doc("A user defined name of the 3rd Party Artifact that is being procured.") name: string; diff --git a/packages/typespec-azure-resource-manager/lib/interfaces.tsp b/packages/typespec-azure-resource-manager/lib/interfaces.tsp index 33eee9102d..9a90ca8511 100644 --- a/packages/typespec-azure-resource-manager/lib/interfaces.tsp +++ b/packages/typespec-azure-resource-manager/lib/interfaces.tsp @@ -43,7 +43,7 @@ interface Operations { */ #deprecated "Use Azure.ResourceManager.TrackedResourceOperations instead" interface ResourceOperations< - Resource extends ArmResource, + Resource extends Foundations.Resource, Properties extends TypeSpec.Reflection.Model, BaseParameters = DefaultBaseParameters > extends TrackedResourceOperations {} @@ -59,7 +59,7 @@ interface ResourceOperations< * */ interface TrackedResourceOperations< - Resource extends ArmResource, + Resource extends Foundations.Resource, Properties extends TypeSpec.Reflection.Model, BaseParameters = DefaultBaseParameters > @@ -79,7 +79,7 @@ interface TrackedResourceOperations< */ #suppress "deprecated" "This should be deprecated in a future release" interface ProxyResourceOperations< - Resource extends ArmResource, + Resource extends Foundations.Resource, BaseParameters = DefaultBaseParameters > extends ResourceRead, @@ -100,7 +100,7 @@ interface ProxyResourceOperations< */ #suppress "deprecated" "This should be deprecated in a future release" interface TenantResourceOperations< - Resource extends ArmResource, + Resource extends Foundations.Resource, Properties extends TypeSpec.Reflection.Model > extends TenantResourceRead, @@ -118,7 +118,7 @@ interface TenantResourceOperations< */ #suppress "deprecated" "This should be deprecated in a future release" interface ResourceInstanceOperations< - Resource extends ArmResource, + Resource extends Foundations.Resource, Properties extends TypeSpec.Reflection.Model, BaseParameters = DefaultBaseParameters, PatchModel = ResourceUpdateModel @@ -134,7 +134,7 @@ interface ResourceInstanceOperations< * @template BaseParameters The http parameters that are part of the request */ interface ResourceCollectionOperations< - Resource extends ArmResource, + Resource extends Foundations.Resource, BaseParameters = DefaultBaseParameters > extends ResourceListByParent, ResourceListBySubscription {} @@ -142,7 +142,7 @@ interface ResourceCollectionOperations< * An interface for resources with can be listed by subscription. * @template Resource The ArmResource that provides these operations */ -interface ResourceListBySubscription { +interface ResourceListBySubscription { /** * @dev List resources by subscription. * @template Resource The ArmResource to list. @@ -158,7 +158,7 @@ interface ResourceListBySubscription { * @template ParentFriendlyName The friendly name of the parent resource */ interface ResourceListByParent< - Resource extends ArmResource, + Resource extends Foundations.Resource, BaseParameters = DefaultBaseParameters, ParentName extends valueof string = "", ParentFriendlyName extends valueof string = "" @@ -179,7 +179,7 @@ interface ResourceListByParent< * @template BaseParameters The http parameters that are part of the request */ interface ResourceRead< - Resource extends ArmResource, + Resource extends Foundations.Resource, BaseParameters = DefaultBaseParameters > { /** @@ -196,7 +196,7 @@ interface ResourceRead< * @template BaseParameters The http parameters that are part of the request */ interface ResourceCreateSync< - Resource extends ArmResource, + Resource extends Foundations.Resource, BaseParameters = DefaultBaseParameters > { /** @@ -213,7 +213,7 @@ interface ResourceCreateSync< * @template BaseParameters The http parameters that are part of the request */ interface ResourceCreateAsync< - Resource extends ArmResource, + Resource extends Foundations.Resource, BaseParameters = DefaultBaseParameters > { /** @@ -233,7 +233,7 @@ interface ResourceCreateAsync< #deprecated "This should be deprecated in a future release" @doc("Delete a resource using the asynchronous call pattern") interface ResourceDeleteAsync< - Resource extends ArmResource, + Resource extends Foundations.Resource, BaseParameters = DefaultBaseParameters > { /** @@ -251,7 +251,7 @@ interface ResourceDeleteAsync< */ @doc("Delete a resource using the asynchronous call pattern") interface ResourceDeleteWithoutOkAsync< - Resource extends ArmResource, + Resource extends Foundations.Resource, BaseParameters = DefaultBaseParameters > { /** @@ -269,7 +269,7 @@ interface ResourceDeleteWithoutOkAsync< */ @doc("Delete a resource") interface ResourceDeleteSync< - Resource extends ArmResource, + Resource extends Foundations.Resource, BaseParameters = DefaultBaseParameters > { /** @@ -288,7 +288,7 @@ interface ResourceDeleteSync< */ @doc("Asynchronous resource update") interface ResourceUpdateAsync< - Resource extends ArmResource, + Resource extends Foundations.Resource, Properties extends TypeSpec.Reflection.Model, BaseParameters = DefaultBaseParameters > { @@ -313,7 +313,7 @@ interface ResourceUpdateAsync< */ @doc("Synchronous resource update") interface ResourceUpdateSync< - Resource extends ArmResource, + Resource extends Foundations.Resource, Properties extends TypeSpec.Reflection.Model, BaseParameters = DefaultBaseParameters > { @@ -333,7 +333,7 @@ interface ResourceUpdateSync< */ #suppress "deprecated" "This should be deprecated in a future release" interface ExtensionResourceInstanceOperations< - Resource extends ArmResource, + Resource extends Foundations.Resource, Properties extends TypeSpec.Reflection.Model > extends ExtensionResourceRead, @@ -345,7 +345,7 @@ interface ExtensionResourceInstanceOperations< * A composite interface for resource collections that include a paginated list operation. * @template Resource The ArmResource that provides these operations */ -interface ExtensionResourceCollectionOperations +interface ExtensionResourceCollectionOperations extends ExtensionResourceList {} /** @@ -354,84 +354,84 @@ interface ExtensionResourceCollectionOperations * @template Properties RP-specific property bag for the resource */ interface ExtensionResourceOperations< - Resource extends ArmResource, + Resource extends Foundations.Resource, Properties extends TypeSpec.Reflection.Model > extends ExtensionResourceInstanceOperations, ExtensionResourceCollectionOperations {} alias ResourceCreate< - Resource extends ArmResource, + Resource extends Foundations.Resource, BaseParameters = DefaultBaseParameters > = ResourceCreateAsync; alias ResourceUpdate< - Resource extends ArmResource, + Resource extends Foundations.Resource, Properties extends TypeSpec.Reflection.Model, BaseParameters = DefaultBaseParameters > = ResourceUpdateSync; #suppress "deprecated" "This should be deprecated in a future release" alias ResourceDelete< - Resource extends ArmResource, + Resource extends Foundations.Resource, BaseParameters = DefaultBaseParameters > = ResourceDeleteAsync; alias ProxyResourceUpdate< - Resource extends ArmResource, + Resource extends Foundations.Resource, Properties extends TypeSpec.Reflection.Model > = ResourceUpdate; -alias ExtensionResourceRead = ResourceRead< +alias ExtensionResourceRead = ResourceRead< Resource, ExtensionBaseParameters >; -alias ExtensionResourceCreate = ResourceCreate< +alias ExtensionResourceCreate = ResourceCreate< Resource, ExtensionBaseParameters >; alias ExtensionResourceUpdate< - Resource extends ArmResource, + Resource extends Foundations.Resource, Properties extends TypeSpec.Reflection.Model > = ResourceUpdate; #suppress "deprecated" "This should be deprecated in a future release" -alias ExtensionResourceDelete = ResourceDelete< +alias ExtensionResourceDelete = ResourceDelete< Resource, ExtensionBaseParameters >; -alias ExtensionResourceList = ResourceListByParent< +alias ExtensionResourceList = ResourceListByParent< Resource, ExtensionBaseParameters, "Extension", "parent" >; -alias TenantResourceRead = ResourceRead< +alias TenantResourceRead = ResourceRead< Resource, TenantBaseParameters >; -alias TenantResourceCreate = ResourceCreateAsync< +alias TenantResourceCreate = ResourceCreateAsync< Resource, TenantBaseParameters >; #suppress "deprecated" "This should be deprecated in a future release" -alias TenantResourceDelete = ResourceDelete< +alias TenantResourceDelete = ResourceDelete< Resource, TenantBaseParameters >; alias TenantResourceUpdate< - Resource extends ArmResource, + Resource extends Foundations.Resource, Properties extends TypeSpec.Reflection.Model > = ResourceUpdate; -alias TenantResourceListByParent = ResourceListByParent< +alias TenantResourceListByParent = ResourceListByParent< Resource, TenantBaseParameters, "Tenant", diff --git a/packages/typespec-azure-resource-manager/lib/models.tsp b/packages/typespec-azure-resource-manager/lib/models.tsp index 41bd9800ed..5b8e266048 100644 --- a/packages/typespec-azure-resource-manager/lib/models.tsp +++ b/packages/typespec-azure-resource-manager/lib/models.tsp @@ -17,7 +17,7 @@ namespace Azure.ResourceManager; * @template NamePattern The RegEx pattern of the name. Default is `^[a-zA-Z0-9-]{3,24}$`. */ model ResourceNameParameter< - Resource extends ArmResource, + Resource extends Foundations.Resource, KeyName extends valueof string = "", SegmentName extends valueof string = "", NamePattern extends valueof string = "^[a-zA-Z0-9-]{3,24}$" @@ -39,7 +39,7 @@ model ResourceNameParameter< @doc("Concrete tracked resource types can be created by aliasing this type using a specific property type.") @armResourceInternal(Properties) @includeInapplicableMetadataInPayload(false) -model TrackedResource extends TrackedResourceBase { +model TrackedResource extends Foundations.TrackedResource { @doc("The resource-specific properties for this resource.") @visibility("read", "create") @extension("x-ms-client-flatten", true) @@ -55,7 +55,7 @@ model TrackedResource extends TrackedResourceBase { @doc("Concrete proxy resource types can be created by aliasing this type using a specific property type.") @armResourceInternal(Properties) @includeInapplicableMetadataInPayload(false) -model ProxyResource extends ProxyResourceBase { +model ProxyResource extends Foundations.ProxyResource { @doc("The resource-specific properties for this resource.") @visibility("read", "create") @extension("x-ms-client-flatten", true) @@ -72,7 +72,7 @@ model ProxyResource extends ProxyResourceBase { @doc("Concrete extension resource types can be created by aliasing this type using a specific property type.") @armResourceInternal(Properties) @includeInapplicableMetadataInPayload(false) -model ExtensionResource extends ExtensionResourceBase { +model ExtensionResource extends Foundations.ExtensionResource { @doc("The resource-specific properties for this resource.") @visibility("read", "create") @extension("x-ms-client-flatten", true) @@ -184,7 +184,8 @@ model DefaultProvisioningStateProperty { * ``` */ model ExtendedLocationProperty { - extendedLocation: Foundations.ExtendedLocation; + @visibility("read", "create") + extendedLocation?: Foundations.ExtendedLocation; } #deprecated "Please change ManagedServiceIdentity to ManagedServiceIdentityProperty." @@ -281,7 +282,7 @@ model ResourceKindProperty { */ @doc("The response of a {name} list operation.", Resource) @friendlyName("{name}ListResult", Resource) -model ResourceListResult is Azure.Core.Page; +model ResourceListResult is Azure.Core.Page; #deprecated "`ResourcePlan` will be deprecated. Please use `ResourcePlanProperty` instead." alias ResourcePlan = ResourcePlanProperty; @@ -301,7 +302,7 @@ alias ResourcePlan = ResourcePlanProperty; @doc("The resource plan property envelope.") model ResourcePlanProperty { @doc("Details of the resource plan.") - plan?: ResourcePlanType; + plan?: Plan; } #deprecated "`ResourceSku` will be deprecated. Please use `ResourceSkuProperty` instead." @@ -322,7 +323,7 @@ alias ResourceSku = ResourceSkuProperty; @doc("The SKU (Stock Keeping Unit) assigned to this resource.") model ResourceSkuProperty { @doc("The SKU (Stock Keeping Unit) assigned to this resource.") - sku?: ResourceSkuType; + sku?: Sku; } #deprecated "`ManagedBy` will be deprecated. Please use `ManagedByProperty` instead." diff --git a/packages/typespec-azure-resource-manager/lib/operations.tsp b/packages/typespec-azure-resource-manager/lib/operations.tsp index ba9ea217bd..48e919b776 100644 --- a/packages/typespec-azure-resource-manager/lib/operations.tsp +++ b/packages/typespec-azure-resource-manager/lib/operations.tsp @@ -21,8 +21,9 @@ namespace Azure.ResourceManager; @segmentOf(Resource) @armResourceList(Resource) @get +@Private.enforceConstraint(Resource, Foundations.Resource) op ArmListBySubscription< - Resource extends ArmResource, + Resource extends Foundations.Resource, Parameters extends {} = {}, Response extends {} = ArmResponse>, Error extends {} = ErrorResponse @@ -44,8 +45,9 @@ op ArmListBySubscription< @segmentOf(Resource) @armRenameListByOperation(Resource, ParentName, ParentFriendlyName) // This must come before @armResourceList! @armResourceList(Resource) +@Private.enforceConstraint(Resource, Foundations.Resource) op ArmResourceListByParent< - Resource extends ArmResource, + Resource extends Foundations.Resource, BaseParameters = DefaultBaseParameters, ParentName extends valueof string = "", ParentFriendlyName extends valueof string = "", @@ -72,8 +74,9 @@ op ArmResourceListByParent< @segmentOf(Resource) @armRenameListByOperation(Resource) // This must come before @armResourceList! @armResourceList(Resource) +@Private.enforceConstraint(Resource, Foundations.Resource) op ArmResourceListAtScope< - Resource extends ArmResource, + Resource extends Foundations.Resource, BaseParameters = DefaultBaseParameters, Parameters extends {} = {}, Response extends {} = ArmResponse>, @@ -97,7 +100,7 @@ op ArmResourceListAtScope< @get @armResourceRead(Resource) op ArmResourceRead< - Resource extends ArmResourceBase, + Resource extends {}, BaseParameters = DefaultBaseParameters, Parameters extends {} = {}, Response extends {} = ArmResponse, @@ -120,7 +123,7 @@ op ArmResourceRead< @doc("Check for the existence of a {name}", Resource) @head op ArmResourceCheckExistence< - Resource extends ArmResourceBase, + Resource extends {}, BaseParameters = DefaultBaseParameters, Parameters extends {} = {}, Response extends {} = ArmResourceExistsResponse | ArmResourceNotFoundResponse, @@ -150,9 +153,10 @@ op ArmResourceCheckExistence< } ) @armResourceCreateOrUpdate(Resource) +@Private.enforceConstraint(Resource, Foundations.Resource) @put op ArmResourceCreateOrUpdateAsync< - Resource extends ArmResource, + Resource extends Foundations.Resource, BaseParameters = DefaultBaseParameters, LroHeaders extends TypeSpec.Reflection.Model = Azure.Core.Foundations.RetryAfterHeader, Parameters extends {} = {}, @@ -180,9 +184,10 @@ op ArmResourceCreateOrUpdateAsync< @autoRoute @doc("Create a {name}", Resource) @armResourceCreateOrUpdate(Resource) +@Private.enforceConstraint(Resource, Foundations.Resource) @put op ArmResourceCreateOrUpdateSync< - Resource extends ArmResource, + Resource extends Foundations.Resource, BaseParameters = DefaultBaseParameters, Parameters extends {} = {}, Response extends {} = ArmResponse, @@ -205,9 +210,10 @@ op ArmResourceCreateOrUpdateSync< @autoRoute @doc("Create a {name}", Resource) @armResourceCreateOrUpdate(Resource) +@Private.enforceConstraint(Resource, Foundations.Resource) @put op ArmResourceCreateOrReplaceSync< - Resource extends ArmResource, + Resource extends Foundations.Resource, BaseParameters = DefaultBaseParameters, Parameters extends {} = {}, Response extends {} = ArmResourceUpdatedResponse | ArmResourceCreatedSyncResponse, @@ -228,8 +234,9 @@ op ArmResourceCreateOrReplaceSync< * @template Response Optional. The success response for the createOrReplace operation * @template Error Optional. The error response, if non-standard. */ +@Private.enforceConstraint(Resource, Foundations.Resource) op ArmResourceCreateOrReplaceAsync< - Resource extends ArmResource, + Resource extends Foundations.Resource, BaseParameters = DefaultBaseParameters, LroHeaders extends TypeSpec.Reflection.Model = Azure.Core.Foundations.RetryAfterHeader, Parameters extends {} = {}, @@ -254,8 +261,9 @@ op ArmResourceCreateOrReplaceAsync< * @template LroHeaders Optional. Allows overriding the lro headers that appear in the Accepted response * @template Parameters Optional. Additional parameters after the path parameters */ +@Private.enforceConstraint(Resource, Foundations.Resource) op ArmTagsPatchAsync< - Resource extends ArmResource, + Resource extends Foundations.Resource, Properties extends {} = TagsUpdateModel, BaseParameters = DefaultBaseParameters, LroHeaders extends TypeSpec.Reflection.Model = ArmLroLocationHeader< @@ -281,8 +289,9 @@ op ArmTagsPatchAsync< * @template LroHeaders Optional. Allows overriding the lro headers returned in the Accepted response * @template Parameters Optional. Additional parameters after the path parameters */ +@Private.enforceConstraint(Resource, Foundations.Resource) op ArmResourcePatchAsync< - Resource extends ArmResource, + Resource extends Foundations.Resource, Properties extends TypeSpec.Reflection.Model, BaseParameters = DefaultBaseParameters, LroHeaders extends TypeSpec.Reflection.Model = ArmLroLocationHeader< @@ -320,9 +329,10 @@ op ArmResourcePatchAsync< } ) @armResourceUpdate(Resource) +@Private.enforceConstraint(Resource, Foundations.Resource) @patch op ArmCustomPatchAsync< - Resource extends ArmResource, + Resource extends Foundations.Resource, PatchModel extends TypeSpec.Reflection.Model = TagsUpdateModel, BaseParameters = DefaultBaseParameters, LroHeaders extends TypeSpec.Reflection.Model = ArmLroLocationHeader< @@ -350,8 +360,9 @@ op ArmCustomPatchAsync< * @template BaseParameters Optional. Allows overriding the operation parameters * @template Parameters Optional. Additional parameters after the path parameters */ +@Private.enforceConstraint(Resource, Foundations.Resource) op ArmTagsPatchSync< - Resource extends ArmResource, + Resource extends Foundations.Resource, BaseParameters = DefaultBaseParameters, Parameters extends {} = {} > is ArmCustomPatchSync, BaseParameters, Parameters>; @@ -363,8 +374,9 @@ op ArmTagsPatchSync< * @template BaseParameters Optional. Allows overriding the operation parameters * @template Parameters Optional. Additional parameters after the path parameters */ +@Private.enforceConstraint(Resource, Foundations.Resource) op ArmResourcePatchSync< - Resource extends ArmResource, + Resource extends Foundations.Resource, Properties extends TypeSpec.Reflection.Model, BaseParameters = DefaultBaseParameters, Parameters extends {} = {} @@ -387,9 +399,10 @@ op ArmResourcePatchSync< @autoRoute @doc("Update a {name}", Resource) @armResourceUpdate(Resource) +@Private.enforceConstraint(Resource, Foundations.Resource) @patch op ArmCustomPatchSync< - Resource extends ArmResource, + Resource extends Foundations.Resource, PatchModel extends TypeSpec.Reflection.Model = TagsUpdateModel, BaseParameters = DefaultBaseParameters, Parameters extends {} = {}, @@ -420,9 +433,10 @@ op ArmCustomPatchSync< } ) @armResourceDelete(Resource) +@Private.enforceConstraint(Resource, Foundations.Resource) @delete op ArmResourceDeleteAsyncBase< - Resource extends ArmResource, + Resource extends Foundations.Resource, Response, BaseParameters = DefaultBaseParameters, Parameters extends {} = {}, @@ -439,8 +453,9 @@ op ArmResourceDeleteAsyncBase< * @template Error Optional. The error response, if non-standard. */ #deprecated "Use 'ArmResourceDeleteWithoutOkAsync' instead" +@Private.enforceConstraint(Resource, Foundations.Resource) op ArmResourceDeleteAsync< - Resource extends ArmResource, + Resource extends Foundations.Resource, BaseParameters = DefaultBaseParameters, LroHeaders extends TypeSpec.Reflection.Model = ArmLroLocationHeader & Azure.Core.Foundations.RetryAfterHeader, @@ -458,8 +473,9 @@ op ArmResourceDeleteAsync< * @template Response Optional. The success response(s) for the delete operation * @template Error Optional. The error response, if non-standard. */ +@Private.enforceConstraint(Resource, Foundations.Resource) op ArmResourceDeleteWithoutOkAsync< - Resource extends ArmResource, + Resource extends Foundations.Resource, BaseParameters = DefaultBaseParameters, LroHeaders extends TypeSpec.Reflection.Model = ArmLroLocationHeader & Azure.Core.Foundations.RetryAfterHeader, @@ -479,9 +495,10 @@ op ArmResourceDeleteWithoutOkAsync< @autoRoute @doc("Delete a {name}", Resource) @armResourceDelete(Resource) +@Private.enforceConstraint(Resource, Foundations.Resource) @delete op ArmResourceDeleteSync< - Resource extends ArmResource, + Resource extends Foundations.Resource, BaseParameters = DefaultBaseParameters, Parameters extends {} = {}, Response extends {} = ArmDeletedResponse | ArmDeletedNoContentResponse, @@ -506,9 +523,10 @@ op ArmResourceDeleteSync< } ) @armResourceAction(Resource) +@Private.enforceConstraint(Resource, Foundations.Resource) @post op ArmResourceActionAsyncBase< - Resource extends ArmResource, + Resource extends Foundations.Resource, Request extends TypeSpec.Reflection.Model | void, Response extends TypeSpec.Reflection.Model | void, BaseParameters extends TypeSpec.Reflection.Model, @@ -534,8 +552,9 @@ op ArmResourceActionAsyncBase< * @template Error Optional. The error response, if non-standard. */ @returnsDoc("Azure operation completed successfully.") +@Private.enforceConstraint(Resource, Foundations.Resource) op ArmResourceActionAsync< - Resource extends ArmResource, + Resource extends Foundations.Resource, Request extends TypeSpec.Reflection.Model | void, Response extends TypeSpec.Reflection.Model | void, BaseParameters extends TypeSpec.Reflection.Model = DefaultBaseParameters, @@ -567,10 +586,11 @@ op ArmResourceActionAsync< */ @autoRoute @armResourceAction(Resource) +@Private.enforceConstraint(Resource, Foundations.Resource) @post @returnsDoc("Azure operation completed successfully.") op ArmResourceActionSync< - Resource extends ArmResource, + Resource extends Foundations.Resource, Request extends TypeSpec.Reflection.Model | void, Response extends TypeSpec.Reflection.Model | void, BaseParameters = DefaultBaseParameters, @@ -594,8 +614,9 @@ op ArmResourceActionSync< * @template Parameters Optional. Additional parameters after the path parameters * @template Error Optional. The error response, if non-standard. */ +@Private.enforceConstraint(Resource, Foundations.Resource) op ArmResourceActionNoContentAsync< - Resource extends ArmResource, + Resource extends Foundations.Resource, Request extends TypeSpec.Reflection.Model | void, BaseParameters extends TypeSpec.Reflection.Model = DefaultBaseParameters, LroHeaders extends TypeSpec.Reflection.Model = ArmLroLocationHeader & @@ -623,8 +644,9 @@ op ArmResourceActionNoContentAsync< * @template Parameters Optional. Additional parameters after the path parameters * @template Error Optional. The error response, if non-standard. */ +@Private.enforceConstraint(Resource, Foundations.Resource) op ArmResourceActionNoResponseContentAsync< - Resource extends ArmResource, + Resource extends Foundations.Resource, Request extends TypeSpec.Reflection.Model | void, BaseParameters extends TypeSpec.Reflection.Model = DefaultBaseParameters, LroHeaders extends TypeSpec.Reflection.Model = ArmLroLocationHeader< @@ -654,9 +676,10 @@ op ArmResourceActionNoResponseContentAsync< */ @autoRoute @armResourceAction(Resource) +@Private.enforceConstraint(Resource, Foundations.Resource) @post op ArmResourceActionNoContentSync< - Resource extends ArmResource, + Resource extends Foundations.Resource, Request extends TypeSpec.Reflection.Model | void, BaseParameters = DefaultBaseParameters, Parameters extends {} = {}, diff --git a/packages/typespec-azure-resource-manager/lib/parameters.tsp b/packages/typespec-azure-resource-manager/lib/parameters.tsp index 4041047bf6..79788ad073 100644 --- a/packages/typespec-azure-resource-manager/lib/parameters.tsp +++ b/packages/typespec-azure-resource-manager/lib/parameters.tsp @@ -150,7 +150,7 @@ model ResourceUriParameter { * @template BaseParameters The parameters representing the base Uri of the resource */ model ResourceInstanceParameters< - Resource extends ArmResourceBase, + Resource extends {}, BaseParameters = DefaultBaseParameters > { ...BaseParameters; @@ -165,7 +165,7 @@ model ResourceInstanceParameters< * @template BaseParameters The parameters representing the base Uri of the resource */ model ResourceParentParameters< - Resource extends ArmResource, + Resource extends Foundations.Resource, BaseParameters = DefaultBaseParameters > { ...BaseParameters; @@ -177,7 +177,7 @@ model ResourceParentParameters< * The dynamic parameters of a list call for an extension resource instance. * @template Resource The extension resource */ -alias ExtensionResourceInstanceParameters = ResourceInstanceParameters< +alias ExtensionResourceInstanceParameters = ResourceInstanceParameters< Resource, ExtensionBaseParameters >; @@ -186,7 +186,7 @@ alias ExtensionResourceInstanceParameters = Resour * The dynamic parameters of a list call for a tenant resource instance. * @template Resource the tenant resource */ -alias TenantInstanceParameters = ResourceInstanceParameters< +alias TenantInstanceParameters = ResourceInstanceParameters< Resource, TenantBaseParameters >; diff --git a/packages/typespec-azure-resource-manager/lib/private.decorators.tsp b/packages/typespec-azure-resource-manager/lib/private.decorators.tsp index 8e770431b6..e825f5fec6 100644 --- a/packages/typespec-azure-resource-manager/lib/private.decorators.tsp +++ b/packages/typespec-azure-resource-manager/lib/private.decorators.tsp @@ -93,3 +93,14 @@ extern dec defaultResourceKeySegmentName( keyName: valueof string, segment: valueof string ); + +/** + * Provides strict contraint type check. + * + * Due to TypeSpec language and all optional properties of `Foundations.Resource`, + * the `Resource extends Foundations.Resource` on many of the standard ARM templates is + * essentially equal to `Resource extends {}` and does not enforce the containt. + * + * Note, this is intended for internal use only for now. + */ +extern dec enforceConstraint(target: Operation | Model, sourceType: Model, constraintType: Model); diff --git a/packages/typespec-azure-resource-manager/lib/responses.tsp b/packages/typespec-azure-resource-manager/lib/responses.tsp index 094f9c79da..7a3a6306e6 100644 --- a/packages/typespec-azure-resource-manager/lib/responses.tsp +++ b/packages/typespec-azure-resource-manager/lib/responses.tsp @@ -92,7 +92,7 @@ model ArmAcceptedLroResponse< model ArmOperationStatus< Properties extends {} = never, StatusValues extends TypeSpec.Reflection.Union = ResourceProvisioningState -> is ArmResourceBase { +> { /** RP-specific properties for the operationStatus resource, only appears when operation ended with Succeeded status */ @visibility("read") properties?: Properties; @@ -204,7 +204,7 @@ model ArmNoContentResponse +model ArmResourceUpdatedResponse is ArmResponse; /** @@ -214,7 +214,7 @@ model ArmResourceUpdatedResponse { ...CreatedResponse; @@ -231,7 +231,7 @@ model ArmResourceCreatedResponse< * @template Resource The resource being updated */ @doc("Resource '{name}' create operation succeeded", Resource) -model ArmResourceCreatedSyncResponse { +model ArmResourceCreatedSyncResponse { ...CreatedResponse; @doc("The body type of the operation request or response.") diff --git a/packages/typespec-azure-resource-manager/src/lib.ts b/packages/typespec-azure-resource-manager/src/lib.ts index 0eeb94b434..4ba733df3b 100644 --- a/packages/typespec-azure-resource-manager/src/lib.ts +++ b/packages/typespec-azure-resource-manager/src/lib.ts @@ -94,6 +94,12 @@ export const $lib = createTypeSpecLibrary({ default: "Resource types must have a property with '@path` and '@segment' decorators.", }, }, + "template-type-constraint-no-met": { + severity: "error", + messages: { + default: paramMessage`The template parameter "${"sourceType"}" for "${"entity"}" does not extend the constraint type "${"constraintType"}". ${"actionMessage"}`, + }, + }, }, }); diff --git a/packages/typespec-azure-resource-manager/src/private.decorators.ts b/packages/typespec-azure-resource-manager/src/private.decorators.ts index f5663f6d11..f52a16aec3 100644 --- a/packages/typespec-azure-resource-manager/src/private.decorators.ts +++ b/packages/typespec-azure-resource-manager/src/private.decorators.ts @@ -48,6 +48,32 @@ export function $omitIfEmpty(context: DecoratorContext, entity: Model, propertyN } } +export function $enforceConstraint( + context: DecoratorContext, + entity: Operation | Model, + sourceType: Model, + constraintType: Model +) { + if (sourceType !== undefined && constraintType !== undefined) { + // walk the baseModel chain until find a match or fail + let baseType: Model | undefined = sourceType; + do { + if (baseType === constraintType) return; + } while ((baseType = baseType.baseModel) !== undefined); + + reportDiagnostic(context.program, { + code: "template-type-constraint-no-met", + target: entity, + format: { + entity: entity.name, + sourceType: sourceType.name, + constraintType: constraintType.name, + actionMessage: `Please use the "TrackedResource", "ProxyResource", or "ExtensionResource" template to define the resource.`, + }, + }); + } +} + export function $resourceBaseParametersOf( context: DecoratorContext, entity: Model, diff --git a/packages/typespec-azure-resource-manager/test/enforce-constraint.test.ts b/packages/typespec-azure-resource-manager/test/enforce-constraint.test.ts new file mode 100644 index 0000000000..b89efdebab --- /dev/null +++ b/packages/typespec-azure-resource-manager/test/enforce-constraint.test.ts @@ -0,0 +1,93 @@ +import { expectDiagnosticEmpty, expectDiagnostics } from "@typespec/compiler/testing"; +import { describe, it } from "vitest"; +import { checkFor } from "./test-host.js"; + +describe("typespec-azure-resource-manager: @enforceConstraint", () => { + it("emits no error when template param extends from Resource", async () => { + const { diagnostics } = await checkFor(` + @armProviderNamespace + @useDependency(Azure.ResourceManager.Versions.v1_0_Preview_1) + namespace Microsoft.Contoso; + + @doc("Widget resource") + model Widget is ProxyResource { + ...ResourceNameParameter; + ...ExtendedLocationProperty; + } + + @doc("The properties of a widget") + model WidgetProperties { + size: int32; + } + + @doc("Direct extended resource") + model CustomResource extends Foundations.Resource {}; + + interface Widgets { + create is ArmResourceCreateOrReplaceSync; + delete is ArmResourceCreateOrReplaceSync; + } + `); + expectDiagnosticEmpty(diagnostics); + }); + + it("emits error if template param is not extended from Resource", async () => { + const { diagnostics } = await checkFor(` + @armProviderNamespace + @useDependency(Azure.ResourceManager.Versions.v1_0_Preview_1) + namespace Microsoft.Contoso; + + @doc("Widget resource") + model Widget { + @doc("Fully qualified resource ID for the resource. Ex - /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}") + @visibility("read") + id?: string; + + @doc("The name of the resource") + @visibility("read") + name?: string; + + @doc("The type of the resource.") + @visibility("read") + type?: string; + + @doc("Azure Resource Manager metadata containing createdBy and modifiedBy information.") + @visibility("read") + systemData?: Foundations.SystemData; + + properties? : WidgetProperties; + } + + @doc("The properties of a widget") + model WidgetProperties { + size: int32; + } + + @doc("Custom Mix in resource") + model CustomResource is Foundations.Resource {}; + + interface Widgets { + create is ArmResourceCreateOrReplaceSync; + delete is ArmResourceCreateOrReplaceSync; + } + `); + expectDiagnostics(diagnostics, [ + { + code: "@azure-tools/typespec-azure-resource-manager/template-type-constraint-no-met", + message: `The template parameter "Widget" for "ArmResourceCreateOrReplaceSync" does not extend the constraint type "Resource". Please use the "TrackedResource", "ProxyResource", or "ExtensionResource" template to define the resource.`, + }, + { + code: "@azure-tools/typespec-azure-resource-manager/template-type-constraint-no-met", + message: `The template parameter "Widget" for "create" does not extend the constraint type "Resource". Please use the "TrackedResource", "ProxyResource", or "ExtensionResource" template to define the resource.`, + }, + { + code: "@azure-tools/typespec-azure-resource-manager/template-type-constraint-no-met", + message: `The template parameter "CustomResource" for "ArmResourceCreateOrReplaceSync" does not extend the constraint type "Resource". Please use the "TrackedResource", "ProxyResource", or "ExtensionResource" template to define the resource.`, + }, + { + code: "@azure-tools/typespec-azure-resource-manager/template-type-constraint-no-met", + message: `The template parameter "CustomResource" for "delete" does not extend the constraint type "Resource". Please use the "TrackedResource", "ProxyResource", or "ExtensionResource" template to define the resource.`, + }, + ]); + }); +}); diff --git a/packages/typespec-azure-resource-manager/test/rules/arm-resource-operations.test.ts b/packages/typespec-azure-resource-manager/test/rules/arm-resource-operations.test.ts index cb23c81ae6..16af1169ab 100644 --- a/packages/typespec-azure-resource-manager/test/rules/arm-resource-operations.test.ts +++ b/packages/typespec-azure-resource-manager/test/rules/arm-resource-operations.test.ts @@ -29,8 +29,6 @@ describe("typespec-azure-resource-manager: arm resource operations rule", () => @armProviderNamespace namespace Microsoft.Foo; - using Azure.ResourceManager.Foundations; - model FooResource is TrackedResource<{}> { @key("foo") @segment("foo") @path name: string; @@ -45,7 +43,7 @@ describe("typespec-azure-resource-manager: arm resource operations rule", () => interface FooResources { @get @armResourceRead(FooResource) get(@key("foo") name: string): ArmResponse | ErrorResponse; @put @armResourceCreateOrUpdate(FooResource) create(...ResourceInstanceParameters, @bodyRoot resource: FooResource): ArmResponse | ArmCreatedResponse | ErrorResponse; - @get @armResourceList(FooResource) listBySubscription(...SubscriptionScope): ArmResponse> | ErrorResponse; + @get @armResourceList(FooResource) listBySubscription(...Foundations.SubscriptionScope): ArmResponse> | ErrorResponse; } ` ) @@ -92,8 +90,6 @@ describe("typespec-azure-resource-manager: arm resource operations rule", () => @useDependency(Azure.ResourceManager.Versions.v1_0_Preview_1) @armProviderNamespace namespace Microsoft.Foo; - - using Azure.ResourceManager.Foundations; model FooResource is TrackedResource<{}> { @key("foo") @segment("foo") @path @@ -107,7 +103,7 @@ describe("typespec-azure-resource-manager: arm resource operations rule", () => @armResourceOperations interface FooResources { - @get @armResourceList(FooResource) listBySubscription(...SubscriptionScope): ArmResponse> | ErrorResponse; + @get @armResourceList(FooResource) listBySubscription(...Foundations.SubscriptionScope): ArmResponse> | ErrorResponse; } ` ) diff --git a/packages/typespec-azure-resource-manager/test/rules/core-operations.test.ts b/packages/typespec-azure-resource-manager/test/rules/core-operations.test.ts index e93acc0d20..c76fa3904a 100644 --- a/packages/typespec-azure-resource-manager/test/rules/core-operations.test.ts +++ b/packages/typespec-azure-resource-manager/test/rules/core-operations.test.ts @@ -28,8 +28,6 @@ describe("typespec-azure-resource-manager: core operations rule", () => { @useDependency(Azure.ResourceManager.Versions.v1_0_Preview_1) @armProviderNamespace namespace Microsoft.Foo; - - using Azure.ResourceManager.Foundations; model FooResource is TrackedResource<{}> { @key("foo") @segment("foo") @path @@ -40,7 +38,7 @@ describe("typespec-azure-resource-manager: core operations rule", () => { interface FooResources extends ResourceCollectionOperations { @put createOrUpdate( ...ResourceInstanceParameters, @bodyRoot resource: FooResource): ArmResponse | ArmCreatedResponse | ErrorResponse; @get get(...ResourceInstanceParameters): ArmResponse | ErrorResponse; - @patch update(...ResourceInstanceParameters, @bodyRoot properties: ResourceUpdateModel): ArmResponse | ErrorResponse; + @patch update(...ResourceInstanceParameters, @bodyRoot properties: Foundations.ResourceUpdateModel): ArmResponse | ErrorResponse; @delete delete(...ResourceInstanceParameters): | ArmDeletedResponse | ArmDeleteAcceptedResponse | ArmDeletedNoContentResponse | ErrorResponse; @post action(...ResourceInstanceParameters) : ArmResponse | ErrorResponse; } diff --git a/packages/typespec-azure-resource-manager/test/rules/patch-operations.test.ts b/packages/typespec-azure-resource-manager/test/rules/patch-operations.test.ts index 1898a4f9a8..72bf418487 100644 --- a/packages/typespec-azure-resource-manager/test/rules/patch-operations.test.ts +++ b/packages/typespec-azure-resource-manager/test/rules/patch-operations.test.ts @@ -102,8 +102,6 @@ describe("typespec-azure-resource-manager: core operations rule", () => { @armProviderNamespace namespace Microsoft.Foo; - using Azure.ResourceManager.Foundations; - @doc(".") enum Versions { @doc(".") @@ -131,7 +129,8 @@ describe("typespec-azure-resource-manager: core operations rule", () => { @doc("A bad patch") model MyBadPatch { ...ManagedServiceIdentityProperty; - ...ArmTagsProperty; + ...Foundations.ArmTagsProperty; + @doc("Blah?") blah?: string; @doc("Blahdeeblah?") diff --git a/packages/typespec-azure-resource-manager/test/rules/retry-after.test.ts b/packages/typespec-azure-resource-manager/test/rules/retry-after.test.ts index 4b728e627f..0220cfe8b9 100644 --- a/packages/typespec-azure-resource-manager/test/rules/retry-after.test.ts +++ b/packages/typespec-azure-resource-manager/test/rules/retry-after.test.ts @@ -24,6 +24,7 @@ describe("typespec-azure-resource-manager: retry-after rule", () => { await tester .expect( ` + @useDependency(Azure.Core.Versions.v1_0_Preview_2) @useDependency(Azure.ResourceManager.Versions.v1_0_Preview_1) @armProviderNamespace namespace Microsoft.Foo;