Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix error when adding revisions to existing APIs #22380

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 22 additions & 9 deletions internal/services/apimanagement/api_management_api_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/hashicorp/terraform-provider-azurerm/helpers/tf"
"github.com/hashicorp/terraform-provider-azurerm/internal/clients"
"github.com/hashicorp/terraform-provider-azurerm/internal/features"
"github.com/hashicorp/terraform-provider-azurerm/internal/services/apimanagement/migration"
"github.com/hashicorp/terraform-provider-azurerm/internal/services/apimanagement/schemaz"
"github.com/hashicorp/terraform-provider-azurerm/internal/services/apimanagement/validate"
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk"
Expand All @@ -41,6 +42,11 @@ func resourceApiManagementApi() *pluginsdk.Resource {
Delete: pluginsdk.DefaultTimeout(30 * time.Minute),
},

SchemaVersion: 1,
StateUpgraders: pluginsdk.StateUpgrades(map[int]pluginsdk.StateUpgrade{
0: migration.ApiV0ToV1{},
}),

Schema: map[string]*pluginsdk.Schema{
"name": schemaz.SchemaApiManagementApiName(),

Expand Down Expand Up @@ -351,8 +357,6 @@ func resourceApiManagementApiCreateUpdate(d *pluginsdk.ResourceData, meta interf
ctx, cancel := timeouts.ForCreateUpdate(meta.(*clients.Client).StopContext, d)
defer cancel()

id := api.NewApiID(subscriptionId, d.Get("resource_group_name").(string), d.Get("api_management_name").(string), d.Get("name").(string))

revision := d.Get("revision").(string)
path := d.Get("path").(string)
apiId := fmt.Sprintf("%s;rev=%s", d.Get("name").(string), revision)
Expand All @@ -363,6 +367,8 @@ func resourceApiManagementApiCreateUpdate(d *pluginsdk.ResourceData, meta interf
protocols := expandApiManagementApiProtocols(protocolsRaw)
sourceApiId := d.Get("source_api_id").(string)

id := api.NewApiID(subscriptionId, d.Get("resource_group_name").(string), d.Get("api_management_name").(string), apiId)

if version != "" && versionSetId == "" {
return fmt.Errorf("setting `version` without the required `version_set_id`")
}
Expand Down Expand Up @@ -412,12 +418,11 @@ func resourceApiManagementApiCreateUpdate(d *pluginsdk.ResourceData, meta interf
log.Printf("[DEBUG] Importing API Management API %q of type %q", id.ApiId, contentFormat)
apiParams := api.ApiCreateOrUpdateParameter{
Properties: &api.ApiCreateOrUpdateProperties{
Type: pointer.To(apiType),
ApiType: pointer.To(soapApiType),
Format: pointer.To(api.ContentFormat(contentFormat)),
Value: pointer.To(contentValue),
Path: path,
ApiVersion: pointer.To(version),
Type: pointer.To(apiType),
ApiType: pointer.To(soapApiType),
Format: pointer.To(api.ContentFormat(contentFormat)),
Value: pointer.To(contentValue),
Path: path,
},
}
wsdlSelectorVs := importV["wsdl_selector"].([]interface{})
Expand All @@ -433,6 +438,10 @@ func resourceApiManagementApiCreateUpdate(d *pluginsdk.ResourceData, meta interf
}
}

if version != "" {
apiParams.Properties.ApiVersion = pointer.To(version)
}

if versionSetId != "" {
apiParams.Properties.ApiVersionSetId = pointer.To(versionSetId)
}
Expand Down Expand Up @@ -474,7 +483,6 @@ func resourceApiManagementApiCreateUpdate(d *pluginsdk.ResourceData, meta interf
Protocols: protocols,
ServiceUrl: pointer.To(serviceUrl),
SubscriptionKeyParameterNames: subscriptionKeyParameterNames,
ApiVersion: pointer.To(version),
SubscriptionRequired: &subscriptionRequired,
AuthenticationSettings: authenticationSettings,
ApiRevisionDescription: pointer.To(d.Get("revision_description").(string)),
Expand All @@ -490,6 +498,11 @@ func resourceApiManagementApiCreateUpdate(d *pluginsdk.ResourceData, meta interf
if displayName != "" {
params.Properties.DisplayName = pointer.To(displayName)
}

if version != "" {
params.Properties.ApiVersion = pointer.To(version)
}

if versionSetId != "" {
params.Properties.ApiVersionSetId = pointer.To(versionSetId)
}
Expand Down
279 changes: 279 additions & 0 deletions internal/services/apimanagement/migration/api_v0_to_v1.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,279 @@
package migration

import (
"context"
"fmt"
"log"

"github.com/hashicorp/go-azure-helpers/resourcemanager/commonschema"
"github.com/hashicorp/terraform-provider-azurerm/internal/services/apimanagement/parse"
"github.com/hashicorp/terraform-provider-azurerm/internal/services/apimanagement/schemaz"
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk"
)

var _ pluginsdk.StateUpgrade = ApiV0ToV1{}

type ApiV0ToV1 struct{}

func (ApiV0ToV1) Schema() map[string]*pluginsdk.Schema {
schema := map[string]*pluginsdk.Schema{
"name": schemaz.SchemaApiManagementApiName(),

"api_management_name": schemaz.SchemaApiManagementName(),

"resource_group_name": commonschema.ResourceGroupName(),

"display_name": {
Type: pluginsdk.TypeString,
Optional: true,
Computed: true,
},

"path": {
Type: pluginsdk.TypeString,
Optional: true,
Computed: true,
},

"protocols": {
Type: pluginsdk.TypeSet,
Optional: true,
Computed: true,
Elem: &pluginsdk.Schema{
Type: pluginsdk.TypeString,
},
},

"revision": {
Type: pluginsdk.TypeString,
Required: true,
ForceNew: true,
},

"revision_description": {
Type: pluginsdk.TypeString,
Optional: true,
},

// Optional
"api_type": {
Type: pluginsdk.TypeString,
Optional: true,
Computed: true,
},

"contact": {
Type: pluginsdk.TypeList,
Optional: true,
MinItems: 1,
MaxItems: 1,
Elem: &pluginsdk.Resource{
Schema: map[string]*pluginsdk.Schema{
"email": {
Type: pluginsdk.TypeString,
Optional: true,
},
"name": {
Type: pluginsdk.TypeString,
Optional: true,
},
"url": {
Type: pluginsdk.TypeString,
Optional: true,
},
},
},
},

"description": {
Type: pluginsdk.TypeString,
Optional: true,
},

"import": {
Type: pluginsdk.TypeList,
Optional: true,
MaxItems: 1,
Elem: &pluginsdk.Resource{
Schema: map[string]*pluginsdk.Schema{
"content_value": {
Type: pluginsdk.TypeString,
Required: true,
},

"content_format": {
Type: pluginsdk.TypeString,
Required: true,
},

"wsdl_selector": {
Type: pluginsdk.TypeList,
Optional: true,
MaxItems: 1,
Elem: &pluginsdk.Resource{
Schema: map[string]*pluginsdk.Schema{
"service_name": {
Type: pluginsdk.TypeString,
Required: true,
},

"endpoint_name": {
Type: pluginsdk.TypeString,
Required: true,
},
},
},
},
},
},
},

"license": {
Type: pluginsdk.TypeList,
Optional: true,
MinItems: 1,
MaxItems: 1,
Elem: &pluginsdk.Resource{
Schema: map[string]*pluginsdk.Schema{
"name": {
Type: pluginsdk.TypeString,
Optional: true,
},
"url": {
Type: pluginsdk.TypeString,
Optional: true,
},
},
},
},

"service_url": {
Type: pluginsdk.TypeString,
Optional: true,
Computed: true,
},

"subscription_key_parameter_names": {
Type: pluginsdk.TypeList,
Optional: true,
Computed: true,
MaxItems: 1,
Elem: &pluginsdk.Resource{
Schema: map[string]*pluginsdk.Schema{
"header": {
Type: pluginsdk.TypeString,
Required: true,
},
"query": {
Type: pluginsdk.TypeString,
Required: true,
},
},
},
},

"subscription_required": {
Type: pluginsdk.TypeBool,
Optional: true,
},

"terms_of_service_url": {
Type: pluginsdk.TypeString,
Optional: true,
},

"source_api_id": {
Type: pluginsdk.TypeString,
Optional: true,
},

"oauth2_authorization": {
Type: pluginsdk.TypeList,
Optional: true,
MaxItems: 1,
Elem: &pluginsdk.Resource{
Schema: map[string]*pluginsdk.Schema{
"authorization_server_name": {
Type: pluginsdk.TypeString,
Required: true,
},
"scope": {
Type: pluginsdk.TypeString,
Optional: true,
},
},
},
},

"openid_authentication": {
Type: pluginsdk.TypeList,
Optional: true,
MaxItems: 1,
Elem: &pluginsdk.Resource{
Schema: map[string]*pluginsdk.Schema{
"openid_provider_name": {
Type: pluginsdk.TypeString,
Required: true,
},
"bearer_token_sending_methods": {
Type: pluginsdk.TypeSet,
Optional: true,
Elem: &pluginsdk.Schema{
Type: pluginsdk.TypeString,
},
},
},
},
},

// Computed
"is_current": {
Type: pluginsdk.TypeBool,
Computed: true,
},

"is_online": {
Type: pluginsdk.TypeBool,
Computed: true,
},

"soap_pass_through": {
Type: pluginsdk.TypeBool,
Computed: true,
Optional: true,
},

"version": {
Type: pluginsdk.TypeString,
Computed: true,
Optional: true,
},

"version_description": {
Type: pluginsdk.TypeString,
Optional: true,
},

"version_set_id": {
Type: pluginsdk.TypeString,
Computed: true,
Optional: true,
},
}

return schema
}

func (ApiV0ToV1) UpgradeFunc() pluginsdk.StateUpgraderFunc {
return func(ctx context.Context, rawState map[string]interface{}, meta interface{}) (map[string]interface{}, error) {
apiId := fmt.Sprintf("%s;rev=%s", rawState["name"], rawState["revision"])
oldId, err := parse.ApiID(rawState["id"].(string))
if err != nil {
return rawState, err
}
newId := parse.NewApiID(oldId.SubscriptionId, oldId.ResourceGroup, oldId.ServiceName, apiId).ID()
log.Printf("[DEBUG] Updating ID from %q to %q", oldId, newId)
rawState["id"] = newId
return rawState, nil
}
}