From 54cf9fd1f2d100c67ed5ddfa686fbe06f670aca9 Mon Sep 17 00:00:00 2001 From: Heng Lu Date: Fri, 17 Nov 2023 16:07:44 +0800 Subject: [PATCH] bugfix: `HEAD` method and other methods combination couldn't be handled correctly --- CHANGELOG.md | 1 + resource/from_swagger.go | 273 +++++++++++++++++++++++++++------- resource/from_swagger_test.go | 198 ++++++++++++++++++++++++ swagger/swagger.go | 3 + 4 files changed, 422 insertions(+), 53 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 75339d70..e30782c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ BUG FIXES: - Fix the bug that coverage reports are generated even if there are no valid test cases. - Fix the bug that other dependency resolvers are not called when error occurs in the previous dependency resolver. - Fix the bug that the generated resources are not in the correct order. +- Fix the bug that `HEAD` method and other methods combination couldn't be handled correctly. ## v0.12.0 FEATURES: diff --git a/resource/from_swagger.go b/resource/from_swagger.go index 4587c86d..8b9a501d 100644 --- a/resource/from_swagger.go +++ b/resource/from_swagger.go @@ -35,8 +35,113 @@ func NewAzapiDefinitionsFromSwagger(apiPath swagger.ApiPath) []types.AzapiDefini label := defaultLabel(apiPath.ResourceType) caser := cases.Title(language.Und, cases.NoLower) + res := make([]types.AzapiDefinition, 0) + coveredMethodMap := make(map[string]bool) switch { + case methodMap[http.MethodGet] && methodMap[http.MethodPut] && methodMap[http.MethodDelete]: + coveredMethodMap[http.MethodGet] = true + coveredMethodMap[http.MethodPut] = true + coveredMethodMap[http.MethodDelete] = true + def.LeadingComments = []string{ + fmt.Sprintf("OperationId: %s, %s, %s", apiPath.OperationIdMap[http.MethodPut], apiPath.OperationIdMap[http.MethodGet], apiPath.OperationIdMap[http.MethodDelete]), + fmt.Sprintf("PUT GET DELETE %s", apiPath.Path), + } + def.Kind = types.KindResource + def.ResourceName = "azapi_resource" + def.AdditionalFields["parent_id"] = types.NewStringLiteralValue(utils.ParentIdOfResourceId(apiPath.Path)) + def.AdditionalFields["name"] = types.NewStringLiteralValue(utils.LastSegment(apiPath.Path)) + def.AdditionalFields["schema_validation_enabled"] = types.NewRawValue("false") + def.Label = label + examplePath := apiPath.ExampleMap[http.MethodPut] + if requestBody, err := RequestBodyFromExample(examplePath); err == nil { + def.Body = requestBody + if requestBody != nil { + if requestBodyMap, ok := def.Body.(map[string]interface{}); ok && requestBody != nil { + if location := requestBodyMap["location"]; location != nil { + def.AdditionalFields["location"] = types.NewStringLiteralValue(location.(string)) + delete(requestBodyMap, "location") + } + if name := requestBodyMap["name"]; name != nil { + delete(requestBodyMap, "name") + } + delete(requestBodyMap, "id") + def.Body = requestBodyMap + } + } + } else { + logrus.Warnf("failed to get request body from example, "+ + "this usually means that the `x-ms-examples` extension is not set correctly for %s in the swagger spec. %v", apiPath.Path, err) + } + if def.Label != "" { + res = append(res, def) + } + case methodMap[http.MethodPut] && methodMap[http.MethodGet]: + coveredMethodMap[http.MethodGet] = true + coveredMethodMap[http.MethodPut] = true + def.LeadingComments = []string{ + fmt.Sprintf("OperationId: %s", apiPath.OperationIdMap[http.MethodPut]), + fmt.Sprintf("PUT %s", apiPath.Path), + } + def.Kind = types.KindResource + def.ResourceName = "azapi_resource_action" + def.AdditionalFields["resource_id"] = types.NewStringLiteralValue(apiPath.Path) + def.AdditionalFields["method"] = types.NewStringLiteralValue(http.MethodPut) + examplePath := apiPath.ExampleMap[http.MethodPut] + if requestBody, err := RequestBodyFromExample(examplePath); err == nil { + def.Body = requestBody + } else { + logrus.Warnf("failed to get request body from example, "+ + "this usually means that the `x-ms-examples` extension is not set correctly for %s in the swagger spec. %v", apiPath.Path, err) + } + def.Label = fmt.Sprintf("put_%s", label) + res = append(res, def) + + def = types.AzapiDefinition{ + Id: apiPath.Path, + AzureResourceType: apiPath.ResourceType, + ApiVersion: apiPath.ApiVersion, + BodyFormat: types.BodyFormatHcl, + AdditionalFields: make(map[string]types.Value), + } + def.LeadingComments = []string{ + fmt.Sprintf("OperationId: %s", apiPath.OperationIdMap[http.MethodGet]), + fmt.Sprintf("GET %s", apiPath.Path), + } + def.Kind = types.KindDataSource + def.ResourceName = "azapi_resource" + def.AdditionalFields["resource_id"] = types.NewStringLiteralValue(apiPath.Path) + def.AdditionalFields["depends_on"] = types.NewRawValue(fmt.Sprintf("[ azapi_resource_action.put_%s ]", label)) + def.Label = label + res = append(res, def) + case methodMap[http.MethodPut]: + coveredMethodMap[http.MethodPut] = true + def.LeadingComments = []string{ + fmt.Sprintf("OperationId: %s", apiPath.OperationIdMap[http.MethodPut]), + fmt.Sprintf("PUT %s", apiPath.Path), + } + def.Kind = types.KindResource + def.ResourceName = "azapi_resource_action" + def.AdditionalFields["resource_id"] = types.NewStringLiteralValue(ResourceIdFromActionPath(apiPath.Path)) + def.AdditionalFields["method"] = types.NewStringLiteralValue(http.MethodPut) + action := utils.ActionName(apiPath.Path) + def.AdditionalFields["action"] = types.NewStringLiteralValue(action) + if action != "" { + def.Label = action + } else { + def.Label = fmt.Sprintf("put_%s", label) + } + examplePath := apiPath.ExampleMap[http.MethodPut] + if requestBody, err := RequestBodyFromExample(examplePath); err == nil { + def.Body = requestBody + } else { + logrus.Warnf("failed to get request body from example, "+ + "this usually means that the `x-ms-examples` extension is not set correctly for %s in the swagger spec. %v", apiPath.Path, err) + } + if def.Label != "" { + res = append(res, def) + } case len(methodMap) == 1 && methodMap[http.MethodGet]: + coveredMethodMap[http.MethodGet] = true def.LeadingComments = []string{ fmt.Sprintf("OperationId: %s", apiPath.OperationIdMap[http.MethodGet]), fmt.Sprintf("%s %s", http.MethodGet, apiPath.Path), @@ -66,7 +171,11 @@ func NewAzapiDefinitionsFromSwagger(apiPath swagger.ApiPath) []types.AzapiDefini def.Label = utils.LastSegment(apiPath.Path) } } + if def.Label != "" { + res = append(res, def) + } case len(methodMap) == 1 && methodMap[http.MethodPost]: + coveredMethodMap[http.MethodPost] = true def.LeadingComments = []string{ fmt.Sprintf("OperationId: %s", apiPath.OperationIdMap[http.MethodPost]), fmt.Sprintf("%s %s", http.MethodPost, apiPath.Path), @@ -90,25 +199,59 @@ func NewAzapiDefinitionsFromSwagger(apiPath swagger.ApiPath) []types.AzapiDefini logrus.Warnf("failed to get request body from example, "+ "this usually means that the `x-ms-examples` extension is not set correctly for %s in the swagger spec. %v", apiPath.Path, err) } + if def.Label != "" { + res = append(res, def) + } + case methodMap[http.MethodGet] && methodMap[http.MethodDelete]: + coveredMethodMap[http.MethodGet] = true + coveredMethodMap[http.MethodDelete] = true + def.LeadingComments = []string{ + fmt.Sprintf("OperationId: %s", apiPath.OperationIdMap[http.MethodGet]), + fmt.Sprintf("GET %s", apiPath.Path), + } + def.Kind = types.KindResource + def.ResourceName = "azapi_resource_action" + def.AdditionalFields["resource_id"] = types.NewStringLiteralValue(apiPath.Path) + def.AdditionalFields["method"] = types.NewStringLiteralValue(http.MethodGet) + def.Label = fmt.Sprintf("get_%s", label) + res = append(res, def) - case methodMap[http.MethodGet] && methodMap[http.MethodPut] && methodMap[http.MethodDelete]: + def = types.AzapiDefinition{ + Id: apiPath.Path, + AzureResourceType: apiPath.ResourceType, + ApiVersion: apiPath.ApiVersion, + BodyFormat: types.BodyFormatHcl, + AdditionalFields: make(map[string]types.Value), + } def.LeadingComments = []string{ - fmt.Sprintf("OperationId: %s, %s, %s", apiPath.OperationIdMap[http.MethodPut], apiPath.OperationIdMap[http.MethodGet], apiPath.OperationIdMap[http.MethodDelete]), - fmt.Sprintf("PUT GET DELETE %s", apiPath.Path), + fmt.Sprintf("OperationId: %s", apiPath.OperationIdMap[http.MethodDelete]), + fmt.Sprintf("DELETE %s", apiPath.Path), } def.Kind = types.KindResource - def.ResourceName = "azapi_resource" - def.AdditionalFields["parent_id"] = types.NewStringLiteralValue(utils.ParentIdOfResourceId(apiPath.Path)) - def.AdditionalFields["name"] = types.NewStringLiteralValue(utils.LastSegment(apiPath.Path)) - def.AdditionalFields["schema_validation_enabled"] = types.NewRawValue("false") - def.Label = label - examplePath := apiPath.ExampleMap[http.MethodPut] + def.ResourceName = "azapi_resource_action" + def.AdditionalFields["resource_id"] = types.NewStringLiteralValue(apiPath.Path) + def.AdditionalFields["method"] = types.NewStringLiteralValue(http.MethodDelete) + def.AdditionalFields["depends_on"] = types.NewRawValue(fmt.Sprintf("[ azapi_resource_action.get_%s ]", label)) + def.Label = fmt.Sprintf("delete_%s", label) + res = append(res, def) + case methodMap[http.MethodGet] && methodMap[http.MethodPatch]: + coveredMethodMap[http.MethodGet] = true + coveredMethodMap[http.MethodPatch] = true + + def.LeadingComments = []string{ + fmt.Sprintf("OperationId: %s", apiPath.OperationIdMap[http.MethodPatch]), + fmt.Sprintf("PATCH %s", apiPath.Path), + } + def.Kind = types.KindResource + def.ResourceName = "azapi_resource_action" + def.AdditionalFields["resource_id"] = types.NewStringLiteralValue(apiPath.Path) + def.AdditionalFields["method"] = types.NewStringLiteralValue(http.MethodPatch) + examplePath := apiPath.ExampleMap[http.MethodPatch] if requestBody, err := RequestBodyFromExample(examplePath); err == nil { def.Body = requestBody if requestBody != nil { if requestBodyMap, ok := def.Body.(map[string]interface{}); ok && requestBody != nil { if location := requestBodyMap["location"]; location != nil { - def.AdditionalFields["location"] = types.NewStringLiteralValue(location.(string)) delete(requestBodyMap, "location") } if name := requestBodyMap["name"]; name != nil { @@ -122,56 +265,30 @@ func NewAzapiDefinitionsFromSwagger(apiPath swagger.ApiPath) []types.AzapiDefini logrus.Warnf("failed to get request body from example, "+ "this usually means that the `x-ms-examples` extension is not set correctly for %s in the swagger spec. %v", apiPath.Path, err) } + def.Label = fmt.Sprintf("patch_%s", label) + res = append(res, def) - case methodMap[http.MethodPut] && methodMap[http.MethodGet]: - def.LeadingComments = []string{ - fmt.Sprintf("OperationId: %s, %s", apiPath.OperationIdMap[http.MethodPut], apiPath.OperationIdMap[http.MethodGet]), - fmt.Sprintf("PUT GET %s", apiPath.Path), - } - def.Kind = types.KindResource - def.ResourceName = "azapi_update_resource" - def.AdditionalFields["parent_id"] = types.NewStringLiteralValue(utils.ParentIdOfResourceId(apiPath.Path)) - def.AdditionalFields["name"] = types.NewStringLiteralValue(utils.LastSegment(apiPath.Path)) - def.Label = label - examplePath := apiPath.ExampleMap[http.MethodPut] - if requestBody, err := RequestBodyFromExample(examplePath); err == nil { - def.Body = requestBody - } else { - logrus.Warnf("failed to get request body from example, "+ - "this usually means that the `x-ms-examples` extension is not set correctly for %s in the swagger spec. %v", apiPath.Path, err) + def = types.AzapiDefinition{ + Id: apiPath.Path, + AzureResourceType: apiPath.ResourceType, + ApiVersion: apiPath.ApiVersion, + BodyFormat: types.BodyFormatHcl, + AdditionalFields: make(map[string]types.Value), } - - case methodMap[http.MethodPut]: def.LeadingComments = []string{ - fmt.Sprintf("OperationId: %s", apiPath.OperationIdMap[http.MethodPut]), - fmt.Sprintf("PUT %s", apiPath.Path), - } - def.Kind = types.KindResource - def.ResourceName = "azapi_resource_action" - def.AdditionalFields["resource_id"] = types.NewStringLiteralValue(ResourceIdFromActionPath(apiPath.Path)) - def.AdditionalFields["method"] = types.NewStringLiteralValue(http.MethodPut) - action := utils.ActionName(apiPath.Path) - def.AdditionalFields["action"] = types.NewStringLiteralValue(action) - if action != "" { - def.Label = action - } else { - def.Label = fmt.Sprintf("put_%s", label) - } - examplePath := apiPath.ExampleMap[http.MethodPut] - if requestBody, err := RequestBodyFromExample(examplePath); err == nil { - def.Body = requestBody - } else { - logrus.Warnf("failed to get request body from example, "+ - "this usually means that the `x-ms-examples` extension is not set correctly for %s in the swagger spec. %v", apiPath.Path, err) + fmt.Sprintf("OperationId: %s", apiPath.OperationIdMap[http.MethodGet]), + fmt.Sprintf("GET %s", apiPath.Path), } - } - - res := make([]types.AzapiDefinition, 0) - if def.Label != "" { + def.Kind = types.KindDataSource + def.ResourceName = "azapi_resource" + def.AdditionalFields["resource_id"] = types.NewStringLiteralValue(apiPath.Path) + def.AdditionalFields["depends_on"] = types.NewRawValue(fmt.Sprintf("[ azapi_resource_action.patch_%s ]", label)) + def.Label = label res = append(res, def) } - if methodMap[http.MethodPatch] { + if methodMap[http.MethodPatch] && !coveredMethodMap[http.MethodPatch] { + coveredMethodMap[http.MethodPatch] = true def := types.AzapiDefinition{ AzureResourceType: apiPath.ResourceType, ApiVersion: apiPath.ApiVersion, @@ -215,6 +332,56 @@ func NewAzapiDefinitionsFromSwagger(apiPath swagger.ApiPath) []types.AzapiDefini res = append(res, def) } + if methodMap[http.MethodHead] { + coveredMethodMap[http.MethodHead] = true + def := types.AzapiDefinition{ + AzureResourceType: apiPath.ResourceType, + ApiVersion: apiPath.ApiVersion, + BodyFormat: types.BodyFormatHcl, + AdditionalFields: make(map[string]types.Value), + } + def.LeadingComments = []string{ + fmt.Sprintf("OperationId: %s", apiPath.OperationIdMap[http.MethodHead]), + fmt.Sprintf("HEAD %s", apiPath.Path), + } + def.Kind = types.KindResource + def.ResourceName = "azapi_resource_action" + def.AdditionalFields["method"] = types.NewStringLiteralValue(http.MethodHead) + def.AdditionalFields["resource_id"] = types.NewStringLiteralValue(ResourceIdFromActionPath(apiPath.Path)) + action := utils.ActionName(apiPath.Path) + def.AdditionalFields["action"] = types.NewStringLiteralValue(action) + if action != "" { + def.Label = action + } else { + def.Label = fmt.Sprintf("head_%s", label) + } + res = append(res, def) + } + + if methodMap[http.MethodDelete] && !coveredMethodMap[http.MethodDelete] { + coveredMethodMap[http.MethodDelete] = true + def.LeadingComments = []string{ + fmt.Sprintf("OperationId: %s", apiPath.OperationIdMap[http.MethodDelete]), + fmt.Sprintf("DELETE %s", apiPath.Path), + } + def.Kind = types.KindResource + def.ResourceName = "azapi_resource_action" + def.AdditionalFields["resource_id"] = types.NewStringLiteralValue(apiPath.Path) + def.AdditionalFields["method"] = types.NewStringLiteralValue(http.MethodDelete) + def.Label = fmt.Sprintf("delete_%s", label) + res = append(res, def) + } + + notCoveredMethods := make([]string, 0) + for method := range methodMap { + if !coveredMethodMap[method] { + notCoveredMethods = append(notCoveredMethods, method) + } + } + if len(notCoveredMethods) != 0 { + // TODO: GET and POST on a collection URL are not supported + logrus.Errorf("there are methods not covered: %v for API path %s", notCoveredMethods, apiPath.Path) + } return res } diff --git a/resource/from_swagger_test.go b/resource/from_swagger_test.go index 6ba40789..222d8d7f 100644 --- a/resource/from_swagger_test.go +++ b/resource/from_swagger_test.go @@ -344,6 +344,204 @@ func Test_Format(t *testing.T) { }, }}, }, + { + ApiPath: swagger.ApiPath{ + Path: "/subscriptions/{subscriptionId}/providers/Microsoft.ApiManagement/locations/{location}/deletedservices/{serviceName}", + ResourceType: "Microsoft.ApiManagement/locations/deletedservices", + ApiVersion: "2022-09-01-preview", + ApiType: swagger.ApiTypeResource, + Methods: []string{"GET", "DELETE"}, + ExampleMap: map[string]string{}, + }, + Expected: []types.AzapiDefinition{ + { + Kind: types.KindResource, + ResourceName: "azapi_resource_action", + Label: "get_deletedservice", + AzureResourceType: "Microsoft.ApiManagement/locations/deletedservices", + ApiVersion: "2022-09-01-preview", + AdditionalFields: map[string]types.Value{ + "method": types.NewStringLiteralValue("GET"), + "resource_id": types.NewStringLiteralValue("/subscriptions/{subscriptionId}/providers/Microsoft.ApiManagement/locations/{location}/deletedservices/{serviceName}"), + }, + }, + { + Kind: types.KindResource, + ResourceName: "azapi_resource_action", + Label: "delete_deletedservice", + AzureResourceType: "Microsoft.ApiManagement/locations/deletedservices", + ApiVersion: "2022-09-01-preview", + AdditionalFields: map[string]types.Value{ + "method": types.NewStringLiteralValue("DELETE"), + "resource_id": types.NewStringLiteralValue("/subscriptions/{subscriptionId}/providers/Microsoft.ApiManagement/locations/{location}/deletedservices/{serviceName}"), + "depends_on": types.NewRawValue("[ azapi_resource_action.get_deletedservice ]"), + }, + }, + }, + }, + { + ApiPath: swagger.ApiPath{ + Path: "/subscriptions/{subscriptionId}/providers/Microsoft.ApiManagement/locations/{location}/deletedservices/{serviceName}", + ResourceType: "Microsoft.ApiManagement/locations/deletedservices", + ApiVersion: "2022-09-01-preview", + ApiType: swagger.ApiTypeResource, + Methods: []string{"HEAD"}, + ExampleMap: map[string]string{}, + }, + Expected: []types.AzapiDefinition{ + { + Kind: types.KindResource, + ResourceName: "azapi_resource_action", + Label: "head_deletedservice", + AzureResourceType: "Microsoft.ApiManagement/locations/deletedservices", + ApiVersion: "2022-09-01-preview", + AdditionalFields: map[string]types.Value{ + "method": types.NewStringLiteralValue("HEAD"), + "resource_id": types.NewStringLiteralValue("/subscriptions/{subscriptionId}/providers/Microsoft.ApiManagement/locations/{location}/deletedservices/{serviceName}"), + "action": types.NewStringLiteralValue(""), + }, + }, + }, + }, + { + ApiPath: swagger.ApiPath{ + Path: "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Automation/automationAccounts/{automationAccountName}/sourceControls/{sourceControlName}", + ResourceType: "Microsoft.Automation/automationAccounts/sourceControls", + ApiVersion: "2022-08-08", + ApiType: swagger.ApiTypeList, + Methods: []string{"GET", "PUT"}, + ExampleMap: map[string]string{ + "GET": path.Clean(path.Join(wd, "testdata", "./examples/sourceControl/getSourceControl.json")), + "PUT": path.Clean(path.Join(wd, "testdata", "./examples/sourceControl/createOrUpdateSourceControl.json")), + }, + }, + Expected: []types.AzapiDefinition{ + { + Kind: types.KindResource, + ResourceName: "azapi_resource_action", + Label: "put_sourceControl", + AzureResourceType: "Microsoft.Automation/automationAccounts/sourceControls", + ApiVersion: "2022-08-08", + AdditionalFields: map[string]types.Value{ + "resource_id": types.NewStringLiteralValue("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Automation/automationAccounts/{automationAccountName}/sourceControls/{sourceControlName}"), + "method": types.NewStringLiteralValue("PUT"), + }, + Body: map[string]interface{}{ + "properties": map[string]interface{}{ + "repoUrl": "https://sampleUser.visualstudio.com/myProject/_git/myRepository", + "branch": "master", + "folderPath": "/folderOne/folderTwo", + "autoSync": true, + "publishRunbook": true, + "sourceType": "VsoGit", + "securityToken": map[string]interface{}{ + "accessToken": "******", + "tokenType": "PersonalAccessToken", + }, + "description": "my description", + }, + }, + }, + { + Kind: types.KindDataSource, + ResourceName: "azapi_resource", + Label: "sourceControl", + AzureResourceType: "Microsoft.Automation/automationAccounts/sourceControls", + ApiVersion: "2022-08-08", + AdditionalFields: map[string]types.Value{ + "resource_id": types.NewStringLiteralValue("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Automation/automationAccounts/{automationAccountName}/sourceControls/{sourceControlName}"), + "depends_on": types.NewRawValue("[ azapi_resource_action.put_sourceControl ]"), + }, + }, + }, + }, + { + ApiPath: swagger.ApiPath{ + Path: "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Automation/automationAccounts/{automationAccountName}/sourceControls/{sourceControlName}", + ResourceType: "Microsoft.Automation/automationAccounts/sourceControls", + ApiVersion: "2022-08-08", + ApiType: swagger.ApiTypeList, + Methods: []string{"GET", "PATCH"}, + ExampleMap: map[string]string{ + "GET": path.Clean(path.Join(wd, "testdata", "./examples/sourceControl/getSourceControl.json")), + "PATCH": path.Clean(path.Join(wd, "testdata", "./examples/sourceControl/createOrUpdateSourceControl.json")), + }, + }, + Expected: []types.AzapiDefinition{ + { + Kind: types.KindResource, + ResourceName: "azapi_resource_action", + Label: "patch_sourceControl", + AzureResourceType: "Microsoft.Automation/automationAccounts/sourceControls", + ApiVersion: "2022-08-08", + AdditionalFields: map[string]types.Value{ + "resource_id": types.NewStringLiteralValue("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Automation/automationAccounts/{automationAccountName}/sourceControls/{sourceControlName}"), + "method": types.NewStringLiteralValue("PATCH"), + }, + Body: map[string]interface{}{ + "properties": map[string]interface{}{ + "repoUrl": "https://sampleUser.visualstudio.com/myProject/_git/myRepository", + "branch": "master", + "folderPath": "/folderOne/folderTwo", + "autoSync": true, + "publishRunbook": true, + "sourceType": "VsoGit", + "securityToken": map[string]interface{}{ + "accessToken": "******", + "tokenType": "PersonalAccessToken", + }, + "description": "my description", + }, + }, + }, + { + Kind: types.KindDataSource, + ResourceName: "azapi_resource", + Label: "sourceControl", + AzureResourceType: "Microsoft.Automation/automationAccounts/sourceControls", + ApiVersion: "2022-08-08", + AdditionalFields: map[string]types.Value{ + "resource_id": types.NewStringLiteralValue("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Automation/automationAccounts/{automationAccountName}/sourceControls/{sourceControlName}"), + "depends_on": types.NewRawValue("[ azapi_resource_action.patch_sourceControl ]"), + }, + }, + }, + }, + { + ApiPath: swagger.ApiPath{ + Path: "/subscriptions/{subscriptionId}/providers/Microsoft.ApiManagement/locations/{location}/deletedservices/{serviceName}", + ResourceType: "Microsoft.ApiManagement/locations/deletedservices", + ApiVersion: "2022-09-01-preview", + ApiType: swagger.ApiTypeResource, + Methods: []string{"HEAD", "DELETE"}, + ExampleMap: map[string]string{}, + }, + Expected: []types.AzapiDefinition{ + { + Kind: types.KindResource, + ResourceName: "azapi_resource_action", + Label: "head_deletedservice", + AzureResourceType: "Microsoft.ApiManagement/locations/deletedservices", + ApiVersion: "2022-09-01-preview", + AdditionalFields: map[string]types.Value{ + "method": types.NewStringLiteralValue("HEAD"), + "resource_id": types.NewStringLiteralValue("/subscriptions/{subscriptionId}/providers/Microsoft.ApiManagement/locations/{location}/deletedservices/{serviceName}"), + "action": types.NewStringLiteralValue(""), + }, + }, + { + Kind: types.KindResource, + ResourceName: "azapi_resource_action", + Label: "delete_deletedservice", + AzureResourceType: "Microsoft.ApiManagement/locations/deletedservices", + ApiVersion: "2022-09-01-preview", + AdditionalFields: map[string]types.Value{ + "method": types.NewStringLiteralValue("DELETE"), + "resource_id": types.NewStringLiteralValue("/subscriptions/{subscriptionId}/providers/Microsoft.ApiManagement/locations/{location}/deletedservices/{serviceName}"), + }, + }, + }, + }, } for _, testcase := range testcases { t.Logf("[DEBUG] Testing path: %v", testcase.ApiPath.Path) diff --git a/swagger/swagger.go b/swagger/swagger.go index 7ea7dba1..ce6f738e 100644 --- a/swagger/swagger.go +++ b/swagger/swagger.go @@ -53,6 +53,9 @@ func Load(swaggerPath string) ([]ApiPath, error) { if pathItem.Patch != nil { operationMap[http.MethodPatch] = *pathItem.Patch } + if pathItem.Head != nil { + operationMap[http.MethodHead] = *pathItem.Head + } methods := make([]string, 0) exampleMap := make(map[string]string)