diff --git a/specification/commerce/cspell.yaml b/specification/commerce/cspell.yaml new file mode 100644 index 000000000000..99cdfc20f70f --- /dev/null +++ b/specification/commerce/cspell.yaml @@ -0,0 +1,11 @@ +# This file configures spell checking. Items in "words" were initially populated +# with words that might be spelling errors. Review these words and take +# appropriate action. For more information, see: https://aka.ms/ci-fix#spell-check + +# Spell checking is not case sensitive +# Keep word lists in alphabetical order so the file is easier to manage +version: '0.2' +import: + - ../../cspell.yaml +words: + - upns diff --git a/specification/commerce/resource-manager/Microsoft.Commerce/OfferCatalog/examples/2026-04-24-preview/Operations_List.json b/specification/commerce/resource-manager/Microsoft.Commerce/OfferCatalog/examples/2026-04-24-preview/Operations_List.json new file mode 100644 index 000000000000..a696d0e3987f --- /dev/null +++ b/specification/commerce/resource-manager/Microsoft.Commerce/OfferCatalog/examples/2026-04-24-preview/Operations_List.json @@ -0,0 +1,35 @@ +{ + "parameters": { + "api-version": "2026-04-24-preview" + }, + "responses": { + "200": { + "body": { + "value": [ + { + "name": "Microsoft.Commerce/upns/read", + "display": { + "provider": "Microsoft.Commerce", + "resource": "upns", + "operation": "Get UPN", + "description": "Returns a single UPN (Unified Product Node) resource by its GUID identifier." + }, + "isDataAction": false + }, + { + "name": "Microsoft.Commerce/upns/list/action", + "display": { + "provider": "Microsoft.Commerce", + "resource": "upns", + "operation": "List UPNs", + "description": "Lists UPN (Unified Product Node) resources at tenant/provider scope." + }, + "isDataAction": false + } + ] + } + } + }, + "operationId": "Operations_List", + "title": "List all operations supported by Microsoft.Commerce/OfferCatalog" +} diff --git a/specification/commerce/resource-manager/Microsoft.Commerce/OfferCatalog/examples/2026-04-24-preview/Upns_Get.json b/specification/commerce/resource-manager/Microsoft.Commerce/OfferCatalog/examples/2026-04-24-preview/Upns_Get.json new file mode 100644 index 000000000000..150db3c7e4e5 --- /dev/null +++ b/specification/commerce/resource-manager/Microsoft.Commerce/OfferCatalog/examples/2026-04-24-preview/Upns_Get.json @@ -0,0 +1,48 @@ +{ + "title": "Get a UPN by its GUID identifier.", + "operationId": "Upns_Get", + "parameters": { + "api-version": "2026-04-24-preview", + "upnGuid": "5ac17b8c-6ac2-432a-b1a9-baa1774c70c5", + "fragments": "pricing,display" + }, + "responses": { + "200": { + "body": { + "id": "/providers/Microsoft.Commerce/upns/5ac17b8c-6ac2-432a-b1a9-baa1774c70c5", + "name": "5ac17b8c-6ac2-432a-b1a9-baa1774c70c5", + "type": "Microsoft.Commerce/upns", + "systemData": { + "lastModifiedAt": "2026-04-15T12:00:00Z" + }, + "properties": { + "valueExchange": { + "id": "5ac17b8c-6ac2-432a-b1a9-baa1774c70c5", + "unit": { + "hint": "vCPU Duration - 1 Hour" + }, + "dimensions": { + "location": "westus2", + "feature": "linux" + } + }, + "product": { + "id": "DZH318Z0BQV6", + "friendlyName": "Container Instances", + "template": "offer-template/az-generic", + "tags": { + "service": "compute" + }, + "ownership": "1PP" + }, + "sku": { + "id": "DZH318TNL8K4", + "friendlyName": "Standard", + "type": "consumption" + }, + "template": "offer-template/az-generic" + } + } + } + } +} diff --git a/specification/commerce/resource-manager/Microsoft.Commerce/OfferCatalog/examples/2026-04-24-preview/Upns_ListByTenant.json b/specification/commerce/resource-manager/Microsoft.Commerce/OfferCatalog/examples/2026-04-24-preview/Upns_ListByTenant.json new file mode 100644 index 000000000000..e19fbbb4a532 --- /dev/null +++ b/specification/commerce/resource-manager/Microsoft.Commerce/OfferCatalog/examples/2026-04-24-preview/Upns_ListByTenant.json @@ -0,0 +1,86 @@ +{ + "title": "List UPNs at tenant/provider scope.", + "operationId": "Upns_ListByTenant", + "parameters": { + "api-version": "2026-04-24-preview" + }, + "responses": { + "200": { + "body": { + "value": [ + { + "id": "/providers/Microsoft.Commerce/upns/5ac17b8c-6ac2-432a-b1a9-baa1774c70c5", + "name": "5ac17b8c-6ac2-432a-b1a9-baa1774c70c5", + "type": "Microsoft.Commerce/upns", + "systemData": { + "lastModifiedAt": "2026-04-15T12:00:00Z" + }, + "properties": { + "valueExchange": { + "id": "5ac17b8c-6ac2-432a-b1a9-baa1774c70c5", + "unit": { + "hint": "vCPU Duration - 1 Hour" + }, + "dimensions": { + "location": "westus2", + "feature": "linux" + } + }, + "product": { + "id": "DZH318Z0BQV6", + "friendlyName": "Container Instances", + "template": "offer-template/az-generic", + "tags": { + "service": "compute" + }, + "ownership": "1PP" + }, + "sku": { + "id": "DZH318TNL8K4", + "friendlyName": "Standard", + "type": "consumption" + }, + "template": "offer-template/az-generic" + } + }, + { + "id": "/providers/Microsoft.Commerce/upns/7b2f9a1c-1234-4567-89ab-cdef01234567", + "name": "7b2f9a1c-1234-4567-89ab-cdef01234567", + "type": "Microsoft.Commerce/upns", + "systemData": { + "lastModifiedAt": "2026-04-14T09:30:00Z" + }, + "properties": { + "valueExchange": { + "id": "7b2f9a1c-1234-4567-89ab-cdef01234567", + "unit": { + "hint": "Subscription - 1 Month" + }, + "dimensions": { + "location": "global", + "feature": "premium" + } + }, + "product": { + "id": "DZH318Z0BPWH", + "friendlyName": "Virtual Machines Ev3 Windows", + "template": "offer-template/az-vm", + "tags": { + "service": "compute" + }, + "ownership": "1PP" + }, + "sku": { + "id": "DZH318Z0BPWH-E16", + "friendlyName": "Standard E16s v3", + "type": "consumption" + }, + "template": "offer-template/az-vm" + } + } + ], + "nextLink": "https://management.azure.com/providers/Microsoft.Commerce/upns?api-version=2026-04-24-preview&$skipToken=abc123" + } + } + } +} diff --git a/specification/commerce/resource-manager/Microsoft.Commerce/OfferCatalog/main.tsp b/specification/commerce/resource-manager/Microsoft.Commerce/OfferCatalog/main.tsp new file mode 100644 index 000000000000..27af9b7b67e8 --- /dev/null +++ b/specification/commerce/resource-manager/Microsoft.Commerce/OfferCatalog/main.tsp @@ -0,0 +1,30 @@ +import "@typespec/http"; +import "@typespec/rest"; +import "@typespec/versioning"; +import "@azure-tools/typespec-azure-core"; +import "@azure-tools/typespec-azure-resource-manager"; +import "./models.tsp"; +import "./upns.tsp"; + +using TypeSpec.Http; +using TypeSpec.Rest; +using TypeSpec.Versioning; +using Azure.Core; +using Azure.ResourceManager; + +/** Microsoft.Commerce OfferCatalog Resource Provider management API. */ +@armProviderNamespace("Microsoft.Commerce") +@service(#{ title: "Microsoft Commerce Offer Catalog" }) +@versioned(Microsoft.Commerce.Versions) +namespace Microsoft.Commerce; + +/** The available API versions for the Offer Catalog service. */ +enum Versions { + /** The 2026-04-24-preview API version. */ + @armCommonTypesVersion(Azure.ResourceManager.CommonTypes.Versions.v6) + @previewVersion + v2026_04_24_preview: "2026-04-24-preview", +} + +/** The operations supported by the Microsoft.Commerce resource provider for the Offer Catalog service. */ +interface Operations extends Azure.ResourceManager.Operations {} diff --git a/specification/commerce/resource-manager/Microsoft.Commerce/OfferCatalog/models.tsp b/specification/commerce/resource-manager/Microsoft.Commerce/OfferCatalog/models.tsp new file mode 100644 index 000000000000..1a5ac214b122 --- /dev/null +++ b/specification/commerce/resource-manager/Microsoft.Commerce/OfferCatalog/models.tsp @@ -0,0 +1,196 @@ +import "@typespec/http"; +import "@typespec/rest"; +import "@azure-tools/typespec-azure-core"; +import "@azure-tools/typespec-azure-resource-manager"; + +using TypeSpec.Http; +using Azure.Core; +using Azure.ResourceManager; + +namespace Microsoft.Commerce; + +/** + * Ownership classification of a product. Indicates whether the product is + * owned by Microsoft (first-party) or by a third-party publisher. + */ +union UpnOwnership { + string, + + /** First-party (Microsoft-owned) product. */ + "1PP", + + /** Third-party (publisher-owned) product. */ + "3PP", +} + +/** The commercial type of a SKU. */ +union SkuType { + string, + + /** Consumption-based SKU (pay-as-you-go). */ + Consumption: "consumption", + + /** Subscription-based SKU. */ + Subscription: "subscription", + + /** One-time purchase SKU. */ + OneTime: "one_time", +} + +/** + * Fragment names that can be requested via the `fragments` query parameter + * on UPN read operations. Each fragment is an opt-in subtree exposed under + * `properties.{fragmentName}` in the response. + */ +union UpnFragment { + string, + + /** Listing and catalog-presentation fragment. */ + Listing: "listing", + + /** List / retail / rate-card pricing fragment (not customer-negotiated pricing). */ + Pricing: "pricing", + + /** Purchase flow configuration fragment. */ + Purchase: "purchase", + + /** Lifecycle metadata fragment. */ + Lifecycle: "lifecycle", + + /** Display metadata fragment. */ + Display: "display", + + /** Tax configuration fragment. */ + Tax: "tax", + + /** Term and billing-plan fragment. */ + Term: "term", + + /** Benefits fragment. */ + Benefits: "benefits", + + /** Bundle composition fragment. */ + Bundle: "bundle", + + /** Eligibility predicates fragment. */ + Eligibility: "eligibility", + + /** Compact channel/market/salesMotion permutations fragment. */ + Permutations: "permutations", + + /** Catalog tags fragment. */ + Tags: "tags", + + /** Search keywords fragment. */ + Search: "search", + + /** Financial classification fragment. */ + Financial: "financial", + + /** External identifiers fragment. */ + ExternalIds: "externalIds", +} + +/** Unit metadata associated with a value exchange. */ +model ValueExchangeUnit { + /** A human-readable hint describing the unit (for example, "vCPU Duration - 1 Hour"). */ + hint?: string; +} + +/** Dimension metadata associated with a value exchange. */ +model ValueExchangeDimensions { + /** The location dimension (for example, an Azure region). */ + location?: string; + + /** The feature dimension (for example, a product feature name). */ + feature?: string; +} + +/** + * Value-exchange (UPN identity) metadata. The value exchange is the leaf of + * the OCP Product -> SKU -> Value Exchange hierarchy and is the transactable + * identity addressed by this resource. + */ +model ValueExchange { + /** The stable identifier of the value exchange. */ + id: string; + + /** Unit metadata for the value exchange. */ + unit?: ValueExchangeUnit; + + /** Dimension metadata for the value exchange. */ + dimensions?: ValueExchangeDimensions; +} + +/** + * Denormalized product summary embedded in a UPN. Only identifying and + * discovery-relevant product fields are exposed here; the full product + * document is not retrievable as a separate resource type. + */ +model ProductSummary { + /** The stable product identifier. */ + id: string; + + /** The human-readable friendly name of the product. */ + friendlyName?: string; + + /** The offer template identifier for this product (for example, "offer-template/az-generic"). */ + template?: string; + + /** Discovery tags associated with the product. */ + #suppress "@azure-tools/typespec-azure-resource-manager/arm-no-record" "Product tags are free-form discovery metadata sourced from the upstream BigCat catalog; the key set is unbounded and cannot be modeled as an explicit type." + tags?: Record; + + /** Ownership classification of the product. */ + ownership?: UpnOwnership; +} + +/** + * Denormalized SKU summary embedded in a UPN. Only identifying and + * discovery-relevant SKU fields are exposed here. + */ +model SkuSummary { + /** The stable SKU identifier. */ + id: string; + + /** The human-readable friendly name of the SKU. */ + friendlyName?: string; + + /** The commercial type of the SKU. */ + type?: SkuType; +} + +/** + * Properties of a UPN (Unified Product Node) resource. A UPN is the + * transactable catalog identity and carries denormalized product and SKU + * summaries plus the value-exchange identity. + */ +#suppress "@azure-tools/typespec-azure-resource-manager/arm-resource-provisioning-state" "UPN is a read-only catalog projection synthesized from the upstream BigCat feed; no ARM provisioning lifecycle applies. The resource has no create/update/delete operations and therefore no provisioning state to track." +model UpnProperties { + /** The value-exchange identity that this UPN represents. */ + valueExchange: ValueExchange; + + /** Denormalized product summary. */ + product: ProductSummary; + + /** Denormalized SKU summary. */ + sku: SkuSummary; + + /** The offer-template identifier for this UPN (for example, "offer-template/az-vm"). */ + template?: string; +} + +/** + * Optional query parameter that allows callers to opt in to fragment + * subtrees on UPN read operations. The value is a comma-separated list of + * fragment names (see `UpnFragment`), or `*` to request all fragments. + * Default (omitted) returns only the identity envelope. + */ +model FragmentsQueryParameter { + /** + * A comma-separated list of fragment names to include in the response, + * or `*` to include all fragments. Example: `pricing,permutations,display`. + */ + @query("fragments") + fragments?: string; +} diff --git a/specification/commerce/resource-manager/Microsoft.Commerce/OfferCatalog/preview/2026-04-24-preview/examples/Operations_List.json b/specification/commerce/resource-manager/Microsoft.Commerce/OfferCatalog/preview/2026-04-24-preview/examples/Operations_List.json new file mode 100644 index 000000000000..a696d0e3987f --- /dev/null +++ b/specification/commerce/resource-manager/Microsoft.Commerce/OfferCatalog/preview/2026-04-24-preview/examples/Operations_List.json @@ -0,0 +1,35 @@ +{ + "parameters": { + "api-version": "2026-04-24-preview" + }, + "responses": { + "200": { + "body": { + "value": [ + { + "name": "Microsoft.Commerce/upns/read", + "display": { + "provider": "Microsoft.Commerce", + "resource": "upns", + "operation": "Get UPN", + "description": "Returns a single UPN (Unified Product Node) resource by its GUID identifier." + }, + "isDataAction": false + }, + { + "name": "Microsoft.Commerce/upns/list/action", + "display": { + "provider": "Microsoft.Commerce", + "resource": "upns", + "operation": "List UPNs", + "description": "Lists UPN (Unified Product Node) resources at tenant/provider scope." + }, + "isDataAction": false + } + ] + } + } + }, + "operationId": "Operations_List", + "title": "List all operations supported by Microsoft.Commerce/OfferCatalog" +} diff --git a/specification/commerce/resource-manager/Microsoft.Commerce/OfferCatalog/preview/2026-04-24-preview/examples/Upns_Get.json b/specification/commerce/resource-manager/Microsoft.Commerce/OfferCatalog/preview/2026-04-24-preview/examples/Upns_Get.json new file mode 100644 index 000000000000..150db3c7e4e5 --- /dev/null +++ b/specification/commerce/resource-manager/Microsoft.Commerce/OfferCatalog/preview/2026-04-24-preview/examples/Upns_Get.json @@ -0,0 +1,48 @@ +{ + "title": "Get a UPN by its GUID identifier.", + "operationId": "Upns_Get", + "parameters": { + "api-version": "2026-04-24-preview", + "upnGuid": "5ac17b8c-6ac2-432a-b1a9-baa1774c70c5", + "fragments": "pricing,display" + }, + "responses": { + "200": { + "body": { + "id": "/providers/Microsoft.Commerce/upns/5ac17b8c-6ac2-432a-b1a9-baa1774c70c5", + "name": "5ac17b8c-6ac2-432a-b1a9-baa1774c70c5", + "type": "Microsoft.Commerce/upns", + "systemData": { + "lastModifiedAt": "2026-04-15T12:00:00Z" + }, + "properties": { + "valueExchange": { + "id": "5ac17b8c-6ac2-432a-b1a9-baa1774c70c5", + "unit": { + "hint": "vCPU Duration - 1 Hour" + }, + "dimensions": { + "location": "westus2", + "feature": "linux" + } + }, + "product": { + "id": "DZH318Z0BQV6", + "friendlyName": "Container Instances", + "template": "offer-template/az-generic", + "tags": { + "service": "compute" + }, + "ownership": "1PP" + }, + "sku": { + "id": "DZH318TNL8K4", + "friendlyName": "Standard", + "type": "consumption" + }, + "template": "offer-template/az-generic" + } + } + } + } +} diff --git a/specification/commerce/resource-manager/Microsoft.Commerce/OfferCatalog/preview/2026-04-24-preview/examples/Upns_ListByTenant.json b/specification/commerce/resource-manager/Microsoft.Commerce/OfferCatalog/preview/2026-04-24-preview/examples/Upns_ListByTenant.json new file mode 100644 index 000000000000..e19fbbb4a532 --- /dev/null +++ b/specification/commerce/resource-manager/Microsoft.Commerce/OfferCatalog/preview/2026-04-24-preview/examples/Upns_ListByTenant.json @@ -0,0 +1,86 @@ +{ + "title": "List UPNs at tenant/provider scope.", + "operationId": "Upns_ListByTenant", + "parameters": { + "api-version": "2026-04-24-preview" + }, + "responses": { + "200": { + "body": { + "value": [ + { + "id": "/providers/Microsoft.Commerce/upns/5ac17b8c-6ac2-432a-b1a9-baa1774c70c5", + "name": "5ac17b8c-6ac2-432a-b1a9-baa1774c70c5", + "type": "Microsoft.Commerce/upns", + "systemData": { + "lastModifiedAt": "2026-04-15T12:00:00Z" + }, + "properties": { + "valueExchange": { + "id": "5ac17b8c-6ac2-432a-b1a9-baa1774c70c5", + "unit": { + "hint": "vCPU Duration - 1 Hour" + }, + "dimensions": { + "location": "westus2", + "feature": "linux" + } + }, + "product": { + "id": "DZH318Z0BQV6", + "friendlyName": "Container Instances", + "template": "offer-template/az-generic", + "tags": { + "service": "compute" + }, + "ownership": "1PP" + }, + "sku": { + "id": "DZH318TNL8K4", + "friendlyName": "Standard", + "type": "consumption" + }, + "template": "offer-template/az-generic" + } + }, + { + "id": "/providers/Microsoft.Commerce/upns/7b2f9a1c-1234-4567-89ab-cdef01234567", + "name": "7b2f9a1c-1234-4567-89ab-cdef01234567", + "type": "Microsoft.Commerce/upns", + "systemData": { + "lastModifiedAt": "2026-04-14T09:30:00Z" + }, + "properties": { + "valueExchange": { + "id": "7b2f9a1c-1234-4567-89ab-cdef01234567", + "unit": { + "hint": "Subscription - 1 Month" + }, + "dimensions": { + "location": "global", + "feature": "premium" + } + }, + "product": { + "id": "DZH318Z0BPWH", + "friendlyName": "Virtual Machines Ev3 Windows", + "template": "offer-template/az-vm", + "tags": { + "service": "compute" + }, + "ownership": "1PP" + }, + "sku": { + "id": "DZH318Z0BPWH-E16", + "friendlyName": "Standard E16s v3", + "type": "consumption" + }, + "template": "offer-template/az-vm" + } + } + ], + "nextLink": "https://management.azure.com/providers/Microsoft.Commerce/upns?api-version=2026-04-24-preview&$skipToken=abc123" + } + } + } +} diff --git a/specification/commerce/resource-manager/Microsoft.Commerce/OfferCatalog/preview/2026-04-24-preview/offerCatalog.json b/specification/commerce/resource-manager/Microsoft.Commerce/OfferCatalog/preview/2026-04-24-preview/offerCatalog.json new file mode 100644 index 000000000000..8a54a7c44ce1 --- /dev/null +++ b/specification/commerce/resource-manager/Microsoft.Commerce/OfferCatalog/preview/2026-04-24-preview/offerCatalog.json @@ -0,0 +1,496 @@ +{ + "swagger": "2.0", + "info": { + "title": "Microsoft Commerce Offer Catalog", + "version": "2026-04-24-preview", + "description": "Microsoft.Commerce OfferCatalog Resource Provider management API.", + "x-typespec-generated": [ + { + "emitter": "@azure-tools/typespec-autorest" + } + ] + }, + "schemes": [ + "https" + ], + "host": "management.azure.com", + "produces": [ + "application/json" + ], + "consumes": [ + "application/json" + ], + "security": [ + { + "azure_auth": [ + "user_impersonation" + ] + } + ], + "securityDefinitions": { + "azure_auth": { + "type": "oauth2", + "description": "Azure Active Directory OAuth2 Flow.", + "flow": "implicit", + "authorizationUrl": "https://login.microsoftonline.com/common/oauth2/authorize", + "scopes": { + "user_impersonation": "impersonate your user account" + } + } + }, + "tags": [ + { + "name": "Operations" + }, + { + "name": "Upns" + } + ], + "paths": { + "/providers/Microsoft.Commerce/operations": { + "get": { + "operationId": "Operations_List", + "tags": [ + "Operations" + ], + "description": "List the operations for the provider", + "parameters": [ + { + "$ref": "../../../../../../common-types/resource-management/v6/types.json#/parameters/ApiVersionParameter" + } + ], + "responses": { + "200": { + "description": "Azure operation completed successfully.", + "schema": { + "$ref": "../../../../../../common-types/resource-management/v6/types.json#/definitions/OperationListResult" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "../../../../../../common-types/resource-management/v6/types.json#/definitions/ErrorResponse" + } + } + }, + "x-ms-examples": { + "List all operations supported by Microsoft.Commerce/OfferCatalog": { + "$ref": "./examples/Operations_List.json" + } + }, + "x-ms-pageable": { + "nextLinkName": "nextLink" + } + } + }, + "/providers/Microsoft.Commerce/upns": { + "get": { + "operationId": "Upns_ListByTenant", + "tags": [ + "Upns" + ], + "description": "List UPN resources at tenant/provider scope. Returns the identity\nenvelope for each UPN by default; use the `fragments` query parameter\nto opt in to additional fragment subtrees on every listed UPN.", + "parameters": [ + { + "$ref": "../../../../../../common-types/resource-management/v6/types.json#/parameters/ApiVersionParameter" + }, + { + "$ref": "#/parameters/FragmentsQueryParameter" + } + ], + "responses": { + "200": { + "description": "Azure operation completed successfully.", + "schema": { + "$ref": "#/definitions/UpnListResult" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "../../../../../../common-types/resource-management/v6/types.json#/definitions/ErrorResponse" + } + } + }, + "x-ms-examples": { + "List UPNs at tenant/provider scope.": { + "$ref": "./examples/Upns_ListByTenant.json" + } + }, + "x-ms-pageable": { + "nextLinkName": "nextLink" + } + } + }, + "/providers/Microsoft.Commerce/upns/{upnGuid}": { + "get": { + "operationId": "Upns_Get", + "tags": [ + "Upns" + ], + "description": "Get a single UPN resource by its GUID identifier. Returns the identity\nenvelope of the UPN.", + "parameters": [ + { + "$ref": "../../../../../../common-types/resource-management/v6/types.json#/parameters/ApiVersionParameter" + }, + { + "name": "upnGuid", + "in": "path", + "description": "The GUID identifier of the UPN. Corresponds to the OCP value-exchange productCode.", + "required": true, + "type": "string", + "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" + } + ], + "responses": { + "200": { + "description": "Azure operation completed successfully.", + "schema": { + "$ref": "#/definitions/Upn" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "../../../../../../common-types/resource-management/v6/types.json#/definitions/ErrorResponse" + } + } + }, + "x-ms-examples": { + "Get a UPN by its GUID identifier.": { + "$ref": "./examples/Upns_Get.json" + } + } + } + } + }, + "definitions": { + "ProductSummary": { + "type": "object", + "description": "Denormalized product summary embedded in a UPN. Only identifying and\ndiscovery-relevant product fields are exposed here; the full product\ndocument is not retrievable as a separate resource type.", + "properties": { + "id": { + "type": "string", + "description": "The stable product identifier." + }, + "friendlyName": { + "type": "string", + "description": "The human-readable friendly name of the product." + }, + "template": { + "type": "string", + "description": "The offer template identifier for this product (for example, \"offer-template/az-generic\")." + }, + "tags": { + "type": "object", + "description": "Discovery tags associated with the product.", + "additionalProperties": { + "type": "string" + } + }, + "ownership": { + "$ref": "#/definitions/UpnOwnership", + "description": "Ownership classification of the product." + } + }, + "required": [ + "id" + ] + }, + "SkuSummary": { + "type": "object", + "description": "Denormalized SKU summary embedded in a UPN. Only identifying and\ndiscovery-relevant SKU fields are exposed here.", + "properties": { + "id": { + "type": "string", + "description": "The stable SKU identifier." + }, + "friendlyName": { + "type": "string", + "description": "The human-readable friendly name of the SKU." + }, + "type": { + "$ref": "#/definitions/SkuType", + "description": "The commercial type of the SKU." + } + }, + "required": [ + "id" + ] + }, + "SkuType": { + "type": "string", + "description": "The commercial type of a SKU.", + "enum": [ + "consumption", + "subscription", + "one_time" + ], + "x-ms-enum": { + "name": "SkuType", + "modelAsString": true, + "values": [ + { + "name": "Consumption", + "value": "consumption", + "description": "Consumption-based SKU (pay-as-you-go)." + }, + { + "name": "Subscription", + "value": "subscription", + "description": "Subscription-based SKU." + }, + { + "name": "OneTime", + "value": "one_time", + "description": "One-time purchase SKU." + } + ] + } + }, + "Upn": { + "type": "object", + "description": "UPN (Unified Product Node) resource.\n\nA UPN is a provider-scoped, tenant-level, read-only proxy resource that\nrepresents one transactable value-exchange in the Microsoft commercial\ncatalog. It is addressed at `/providers/Microsoft.Commerce/upns/{upnGuid}`.", + "properties": { + "properties": { + "$ref": "#/definitions/UpnProperties", + "description": "The properties of the UPN resource." + } + }, + "allOf": [ + { + "$ref": "../../../../../../common-types/resource-management/v6/types.json#/definitions/ProxyResource" + } + ] + }, + "UpnFragment": { + "type": "string", + "description": "Fragment names that can be requested via the `fragments` query parameter\non UPN read operations. Each fragment is an opt-in subtree exposed under\n`properties.{fragmentName}` in the response.", + "enum": [ + "listing", + "pricing", + "purchase", + "lifecycle", + "display", + "tax", + "term", + "benefits", + "bundle", + "eligibility", + "permutations", + "tags", + "search", + "financial", + "externalIds" + ], + "x-ms-enum": { + "name": "UpnFragment", + "modelAsString": true, + "values": [ + { + "name": "Listing", + "value": "listing", + "description": "Listing and catalog-presentation fragment." + }, + { + "name": "Pricing", + "value": "pricing", + "description": "List / retail / rate-card pricing fragment (not customer-negotiated pricing)." + }, + { + "name": "Purchase", + "value": "purchase", + "description": "Purchase flow configuration fragment." + }, + { + "name": "Lifecycle", + "value": "lifecycle", + "description": "Lifecycle metadata fragment." + }, + { + "name": "Display", + "value": "display", + "description": "Display metadata fragment." + }, + { + "name": "Tax", + "value": "tax", + "description": "Tax configuration fragment." + }, + { + "name": "Term", + "value": "term", + "description": "Term and billing-plan fragment." + }, + { + "name": "Benefits", + "value": "benefits", + "description": "Benefits fragment." + }, + { + "name": "Bundle", + "value": "bundle", + "description": "Bundle composition fragment." + }, + { + "name": "Eligibility", + "value": "eligibility", + "description": "Eligibility predicates fragment." + }, + { + "name": "Permutations", + "value": "permutations", + "description": "Compact channel/market/salesMotion permutations fragment." + }, + { + "name": "Tags", + "value": "tags", + "description": "Catalog tags fragment." + }, + { + "name": "Search", + "value": "search", + "description": "Search keywords fragment." + }, + { + "name": "Financial", + "value": "financial", + "description": "Financial classification fragment." + }, + { + "name": "ExternalIds", + "value": "externalIds", + "description": "External identifiers fragment." + } + ] + } + }, + "UpnListResult": { + "type": "object", + "description": "The response of a Upn list operation.", + "properties": { + "value": { + "type": "array", + "description": "The Upn items on this page", + "items": { + "$ref": "#/definitions/Upn" + } + }, + "nextLink": { + "type": "string", + "format": "uri", + "description": "The link to the next page of items" + } + }, + "required": [ + "value" + ] + }, + "UpnOwnership": { + "type": "string", + "description": "Ownership classification of a product. Indicates whether the product is\nowned by Microsoft (first-party) or by a third-party publisher.", + "enum": [ + "1PP", + "3PP" + ], + "x-ms-enum": { + "name": "UpnOwnership", + "modelAsString": true, + "values": [ + { + "name": "1PP", + "value": "1PP", + "description": "First-party (Microsoft-owned) product." + }, + { + "name": "3PP", + "value": "3PP", + "description": "Third-party (publisher-owned) product." + } + ] + } + }, + "UpnProperties": { + "type": "object", + "description": "Properties of a UPN (Unified Product Node) resource. A UPN is the\ntransactable catalog identity and carries denormalized product and SKU\nsummaries plus the value-exchange identity.", + "properties": { + "valueExchange": { + "$ref": "#/definitions/ValueExchange", + "description": "The value-exchange identity that this UPN represents." + }, + "product": { + "$ref": "#/definitions/ProductSummary", + "description": "Denormalized product summary." + }, + "sku": { + "$ref": "#/definitions/SkuSummary", + "description": "Denormalized SKU summary." + }, + "template": { + "type": "string", + "description": "The offer-template identifier for this UPN (for example, \"offer-template/az-vm\")." + } + }, + "required": [ + "valueExchange", + "product", + "sku" + ] + }, + "ValueExchange": { + "type": "object", + "description": "Value-exchange (UPN identity) metadata. The value exchange is the leaf of\nthe OCP Product -> SKU -> Value Exchange hierarchy and is the transactable\nidentity addressed by this resource.", + "properties": { + "id": { + "type": "string", + "description": "The stable identifier of the value exchange." + }, + "unit": { + "$ref": "#/definitions/ValueExchangeUnit", + "description": "Unit metadata for the value exchange." + }, + "dimensions": { + "$ref": "#/definitions/ValueExchangeDimensions", + "description": "Dimension metadata for the value exchange." + } + }, + "required": [ + "id" + ] + }, + "ValueExchangeDimensions": { + "type": "object", + "description": "Dimension metadata associated with a value exchange.", + "properties": { + "location": { + "type": "string", + "description": "The location dimension (for example, an Azure region)." + }, + "feature": { + "type": "string", + "description": "The feature dimension (for example, a product feature name)." + } + } + }, + "ValueExchangeUnit": { + "type": "object", + "description": "Unit metadata associated with a value exchange.", + "properties": { + "hint": { + "type": "string", + "description": "A human-readable hint describing the unit (for example, \"vCPU Duration - 1 Hour\")." + } + } + } + }, + "parameters": { + "FragmentsQueryParameter": { + "name": "fragments", + "in": "query", + "description": "A comma-separated list of fragment names to include in the response,\nor `*` to include all fragments. Example: `pricing,permutations,display`.", + "required": false, + "type": "string", + "x-ms-parameter-location": "method" + } + } +} diff --git a/specification/commerce/resource-manager/Microsoft.Commerce/OfferCatalog/readme.md b/specification/commerce/resource-manager/Microsoft.Commerce/OfferCatalog/readme.md new file mode 100644 index 000000000000..2c9930f47938 --- /dev/null +++ b/specification/commerce/resource-manager/Microsoft.Commerce/OfferCatalog/readme.md @@ -0,0 +1,53 @@ +# Microsoft.Commerce OfferCatalog + +> see https://aka.ms/autorest + +This is the AutoRest configuration file for the Microsoft.Commerce Offer Catalog service. + +--- + +## Getting Started + +To build the SDK for Microsoft.Commerce Offer Catalog, simply [Install AutoRest](https://aka.ms/autorest) and in this folder, run: + +> `autorest` + +--- + +## Configuration + +### Basic Information + +These are the global settings for the Offer Catalog API. + +```yaml +openapi-type: arm +tag: package-2026-04-24-preview +``` + +### Tag: package-2026-04-24-preview + +These settings apply only when `--tag=package-2026-04-24-preview` is specified on the command line. + +```yaml $(tag) == 'package-2026-04-24-preview' +input-file: + - preview/2026-04-24-preview/offerCatalog.json +``` + +--- + +# Code Generation + +## Swagger to SDK + +This section describes what SDK should be generated by the automatic system. +This is not used by Autorest itself. + +``` yaml $(swagger-to-sdk) +swagger-to-sdk: + - repo: azure-sdk-for-net + - repo: azure-sdk-for-python + - repo: azure-sdk-for-java + - repo: azure-sdk-for-js + - repo: azure-sdk-for-go +``` diff --git a/specification/commerce/resource-manager/Microsoft.Commerce/OfferCatalog/tspconfig.yaml b/specification/commerce/resource-manager/Microsoft.Commerce/OfferCatalog/tspconfig.yaml new file mode 100644 index 000000000000..d3cf2f7fda90 --- /dev/null +++ b/specification/commerce/resource-manager/Microsoft.Commerce/OfferCatalog/tspconfig.yaml @@ -0,0 +1,15 @@ +parameters: + "service-dir": + default: "sdk/commerce" +emit: + - "@azure-tools/typespec-autorest" +options: + "@azure-tools/typespec-autorest": + emitter-output-dir: "{project-root}" + output-file: "{version-status}/{version}/offerCatalog.json" + examples-dir: "{project-root}/examples" + arm-types-dir: "{project-root}/../../../../common-types/resource-management" + use-read-only-status-schema: true +linter: + extends: + - "@azure-tools/typespec-azure-rulesets/resource-manager" diff --git a/specification/commerce/resource-manager/Microsoft.Commerce/OfferCatalog/upns.tsp b/specification/commerce/resource-manager/Microsoft.Commerce/OfferCatalog/upns.tsp new file mode 100644 index 000000000000..9e83a26b3f96 --- /dev/null +++ b/specification/commerce/resource-manager/Microsoft.Commerce/OfferCatalog/upns.tsp @@ -0,0 +1,55 @@ +import "@typespec/http"; +import "@typespec/rest"; +import "@azure-tools/typespec-azure-core"; +import "@azure-tools/typespec-azure-resource-manager"; +import "./models.tsp"; + +using TypeSpec.Http; +using TypeSpec.Rest; +using Azure.Core; +using Azure.ResourceManager; + +namespace Microsoft.Commerce; + +/** + * UPN (Unified Product Node) resource. + * + * A UPN is a provider-scoped, tenant-level, read-only proxy resource that + * represents one transactable value-exchange in the Microsoft commercial + * catalog. It is addressed at `/providers/Microsoft.Commerce/upns/{upnGuid}`. + */ +@tenantResource +model Upn is Azure.ResourceManager.ProxyResource { + ...ResourceNameParameter< + Resource = Upn, + KeyName = "upnGuid", + SegmentName = "upns", + NamePattern = "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" + >; +} + +/** Read-only operations on UPN catalog resources. */ +@armResourceOperations +interface Upns { + /** + * Get a single UPN resource by its GUID identifier. Returns the identity + * envelope of the UPN. + */ + get is Extension.Read; + + /** + * List UPN resources at tenant/provider scope. Returns the identity + * envelope for each UPN by default; use the `fragments` query parameter + * to opt in to additional fragment subtrees on every listed UPN. + */ + listByTenant is Extension.ListByTarget< + Extension.Tenant, + Upn, + Parameters = FragmentsQueryParameter + >; +} + +@@doc(Upn.name, + "The GUID identifier of the UPN. Corresponds to the OCP value-exchange productCode." +); +@@doc(Upn.properties, "The properties of the UPN resource.");