Skip to content

Commit

Permalink
Improvements to Microsoft.AzureTerraform TypeSpec
Browse files Browse the repository at this point in the history
Based from .NET SDK review:

1. Use ArmOperationStatus from library instead of defining our own
2. Wrap both exportTerraform and operationStatuses operations in single ExportTerraform interface
3. Added client.tsp override so the generated method name for .NET SDK complies with the guidelines
4. Removed unecessary suppresses and DRY-ed response types
  • Loading branch information
gerrytan committed Oct 11, 2024
1 parent fda3d5e commit 35f4729
Show file tree
Hide file tree
Showing 8 changed files with 112 additions and 104 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import "@azure-tools/typespec-client-generator-core";
import "./main.tsp";

using Azure.ClientGenerator.Core;
using Microsoft.AzureTerraform;

@@clientName(ExportTerraform.exportTerraform, "ExportTerraform", "csharp");
@@clientName(ExportTerraform.operationStatuses, "OperationStatuses", "csharp");
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"title": "ExportTerraform",
"operationId": "ExportTerraform",
"operationId": "ExportTerraform_ExportTerraform",
"parameters": {
"api-version": "2023-07-01-preview",
"subscriptionId": "00000000-0000-0000-0000-000000000000",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"title": "Get specific operation status",
"operationId": "OperationStatuses_Get",
"operationId": "ExportTerraform_OperationStatuses",
"parameters": {
"subscriptionId": "00000000-0000-0000-0000-000000000000",
"operationId": "00000000-0000-0000-0000-000000000000",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,44 +93,14 @@ model ExportResourceGroup extends BaseExportModel {
}

@doc("The status of the LRO operation.")
model OperationStatus {
@doc("The operation status resource id.")
id?: string;

@doc("The fully qualified resource id of the resource for which the operation was performed.")
@visibility("read")
resourceId?: string;

@doc("The operation name.")
name?: string;

@doc("The start time of the operation.")
@visibility("read")
startTime?: utcDateTime;

@doc("The end time of the operation.")
@visibility("read")
endTime?: utcDateTime;

@doc("The status of the operation.")
status?: string;

@doc("The progress percentage of the operation, ranges from 0 to 100")
percentComplete?: float64;

@doc("The Terraform export result")
properties?: ExportResult;

...ErrorResponse;
}

model InProgressOperationStatus
is ArmAcceptedResponse<
"InProgress operation status",
ArmCombinedLroHeaders & Azure.Core.Foundations.RetryAfterHeader
> {
...OperationStatus;
}
model OperationStatus is ArmOperationStatus<ExportResult>;

model AcceptedLroResponse<Description extends valueof string>
is ArmAcceptedLroResponse<
Description,
ArmCombinedLroHeaders<ArmOperationStatus, OperationStatus> &
Azure.Core.Foundations.RetryAfterHeader
>;

@doc("The Terraform export result")
model ExportResult {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,52 +2,47 @@ import "@azure-tools/typespec-azure-core";
import "@typespec/rest";
import "./models.tsp";
import "@azure-tools/typespec-azure-resource-manager";
import "@azure-tools/typespec-client-generator-core";

using TypeSpec.Rest;
using TypeSpec.Http;
using Azure.Core;
using Azure.ClientGenerator.Core;
using Azure.ResourceManager;
using Azure.ResourceManager.Foundations;
using OpenAPI;

namespace Microsoft.AzureTerraform;

#suppress "@azure-tools/typespec-azure-resource-manager/arm-resource-operation" "Cannot use @armResourceOperations decorator here, the auto-generated routes do not match feature requirements"
#suppress "@azure-tools/typespec-azure-core/no-openapi" "TODO: migrate to LRO concepts DO NOT USE x-ms-long-running-operation-options"
@doc("Exports the Terraform configuration of the specified resource(s).")
@route("/subscriptions/{subscriptionId}/providers/Microsoft.AzureTerraform/exportTerraform")
@post
@tag("ExportTerraform")
@extension(
"x-ms-long-running-operation-options",
{
`final-state-via`: "azure-async-operation",
`final-state-schema`: "#/definitions/OperationStatus",
}
)
op exportTerraform(
...ApiVersionParameter,
...SubscriptionIdParameter,
@doc("Parameters common to all ExportTerraform operations")
model CommonExportTerraformParameters {
...ApiVersionParameter;
...SubscriptionIdParameter;
}

#suppress "@azure-tools/typespec-azure-resource-manager/arm-resource-interface-requires-decorator" "Cannot use @armResourceOperations decorator, the implied @autoRoute forces {subscriptionId} path param to be at the end"
interface ExportTerraform {
#suppress "@azure-tools/typespec-azure-resource-manager/arm-resource-operation" "Cannot use @armResourceOperation, API is not bound to a single resource type"
@doc("Exports the Terraform configuration of the specified resource(s).")
@route("/subscriptions/{subscriptionId}/providers/Microsoft.AzureTerraform/exportTerraform")
@post
@tag("ExportTerraform")
@pollingOperation(ExportTerraform.operationStatuses)
exportTerraform(
...CommonExportTerraformParameters,

@doc("The export parameter")
@body
exportParameter: BaseExportModel,
): ArmAcceptedLroResponse<
"Export request accepted.",
ArmCombinedLroHeaders<ArmOperationStatus, OperationStatus> &
Azure.Core.Foundations.RetryAfterHeader
> | ErrorResponse;
@doc("The export parameter")
@body
exportParameter: BaseExportModel,
): AcceptedLroResponse<"Export request accepted."> | ErrorResponse;

#suppress "@azure-tools/typespec-azure-resource-manager/arm-resource-interface-requires-decorator" "Cannot use @armResourceOperations decorator here, the auto-generated routes do not match feature requirements"
interface OperationStatuses {
#suppress "@azure-tools/typespec-azure-resource-manager/no-response-body" "Body of 202 is not empty: not compatible with API requirements"
#suppress "@azure-tools/typespec-azure-resource-manager/arm-resource-operation" "Cannot use @armResourceRead, API is not bound to a single resource type"
@doc("Get the status of a long running azure asynchronous operation.")
@route("/subscriptions/{subscriptionId}/providers/Microsoft.AzureTerraform/operationStatuses/{operationId}")
@get
@tag("OperationStatuses")
@armResourceRead(ArmResponse<OperationStatus>)
get(
operationStatuses(
...OperationIdParameter,
...ApiVersionParameter,
...SubscriptionIdParameter,
): OperationStatus | InProgressOperationStatus | ErrorResponse;
...CommonExportTerraformParameters,
): OperationStatus | AcceptedLroResponse<"InProgress operation status"> | ErrorResponse;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"title": "ExportTerraform",
"operationId": "ExportTerraform",
"operationId": "ExportTerraform_ExportTerraform",
"parameters": {
"api-version": "2023-07-01-preview",
"subscriptionId": "00000000-0000-0000-0000-000000000000",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"title": "Get specific operation status",
"operationId": "OperationStatuses_Get",
"operationId": "ExportTerraform_OperationStatuses",
"parameters": {
"subscriptionId": "00000000-0000-0000-0000-000000000000",
"operationId": "00000000-0000-0000-0000-000000000000",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@
},
"tags": [
{
"name": "ExportTerraform"
"name": "Operations"
},
{
"name": "Operations"
"name": "ExportTerraform"
},
{
"name": "OperationStatuses"
Expand Down Expand Up @@ -88,7 +88,7 @@
},
"/subscriptions/{subscriptionId}/providers/Microsoft.AzureTerraform/exportTerraform": {
"post": {
"operationId": "ExportTerraform",
"operationId": "ExportTerraform_ExportTerraform",
"tags": [
"ExportTerraform"
],
Expand Down Expand Up @@ -143,15 +143,14 @@
}
},
"x-ms-long-running-operation-options": {
"final-state-via": "azure-async-operation",
"final-state-schema": "#/definitions/OperationStatus"
"final-state-via": "location"
},
"x-ms-long-running-operation": true
}
},
"/subscriptions/{subscriptionId}/providers/Microsoft.AzureTerraform/operationStatuses/{operationId}": {
"get": {
"operationId": "OperationStatuses_Get",
"operationId": "ExportTerraform_OperationStatuses",
"tags": [
"OperationStatuses"
],
Expand All @@ -176,9 +175,6 @@
},
"202": {
"description": "InProgress operation status",
"schema": {
"$ref": "#/definitions/OperationStatus"
},
"headers": {
"Azure-AsyncOperation": {
"type": "string",
Expand Down Expand Up @@ -212,6 +208,42 @@
}
},
"definitions": {
"Azure.Core.uuid": {
"type": "string",
"format": "uuid",
"description": "Universally Unique Identifier"
},
"Azure.ResourceManager.ResourceProvisioningState": {
"type": "string",
"description": "The provisioning state of a resource type.",
"enum": [
"Succeeded",
"Failed",
"Canceled"
],
"x-ms-enum": {
"name": "ResourceProvisioningState",
"modelAsString": true,
"values": [
{
"name": "Succeeded",
"value": "Succeeded",
"description": "Resource has been created."
},
{
"name": "Failed",
"value": "Failed",
"description": "Resource creation failed."
},
{
"name": "Canceled",
"value": "Canceled",
"description": "Resource creation was canceled."
}
]
},
"readOnly": true
},
"BaseExportModel": {
"type": "object",
"description": "The base export parameter",
Expand Down Expand Up @@ -379,49 +411,52 @@
"type": "object",
"description": "The status of the LRO operation.",
"properties": {
"id": {
"type": "string",
"description": "The operation status resource id."
},
"resourceId": {
"type": "string",
"description": "The fully qualified resource id of the resource for which the operation was performed.",
"properties": {
"$ref": "#/definitions/ExportResult",
"description": "RP-specific properties for the operationStatus resource, only appears when operation ended with Succeeded status",
"readOnly": true
},
"status": {
"$ref": "#/definitions/Azure.ResourceManager.ResourceProvisioningState",
"description": "The operation status"
},
"id": {
"$ref": "#/definitions/Azure.Core.uuid",
"description": "The unique identifier for the operationStatus resource"
},
"name": {
"type": "string",
"description": "The operation name."
"description": "The name of the operationStatus resource",
"readOnly": true
},
"startTime": {
"type": "string",
"format": "date-time",
"description": "The start time of the operation.",
"description": "Operation start time",
"readOnly": true
},
"endTime": {
"type": "string",
"format": "date-time",
"description": "The end time of the operation.",
"description": "Operation complete time",
"readOnly": true
},
"status": {
"type": "string",
"description": "The status of the operation."
},
"percentComplete": {
"type": "number",
"format": "double",
"description": "The progress percentage of the operation, ranges from 0 to 100"
},
"properties": {
"$ref": "#/definitions/ExportResult",
"description": "The Terraform export result"
"description": "The progress made toward completing the operation",
"readOnly": true
},
"error": {
"$ref": "../../../../../common-types/resource-management/v5/types.json#/definitions/ErrorDetail",
"description": "The error object."
"description": "Errors that occurred if the operation ended with Canceled or Failed status",
"readOnly": true
}
}
},
"required": [
"status",
"id"
]
},
"Type": {
"type": "string",
Expand Down

0 comments on commit 35f4729

Please sign in to comment.