forked from hashicorp/terraform-provider-azurerm
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
new resource "azurerm_data_factory_linked_custom_service" (hashicorp#…
…12224) fix hashicorp#9860 fix hashicorp#9431 a generic resource for data factory linked service. Users could use a json string and construct a specific type linked service. the same with azure cli implementation docs.microsoft.com/en-us/cli/azure/datafactory/linked-service?view=azure-cli-latest#az_datafactory_linked_service_create there are some sensitive properties in property_json not returned in the response, so not set it in read function and no supressDiff func.
- Loading branch information
Showing
4 changed files
with
768 additions
and
0 deletions.
There are no files selected for viewing
335 changes: 335 additions & 0 deletions
335
azurerm/internal/services/datafactory/data_factory_linked_custom_service_resource.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,335 @@ | ||
package datafactory | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"time" | ||
|
||
"github.com/Azure/azure-sdk-for-go/services/datafactory/mgmt/2018-06-01/datafactory" | ||
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" | ||
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients" | ||
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/datafactory/parse" | ||
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/datafactory/validate" | ||
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tf/pluginsdk" | ||
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tf/validation" | ||
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/timeouts" | ||
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" | ||
) | ||
|
||
func resourceDataFactoryLinkedCustomService() *pluginsdk.Resource { | ||
return &pluginsdk.Resource{ | ||
Create: resourceDataFactoryLinkedCustomServiceCreateUpdate, | ||
Read: resourceDataFactoryLinkedCustomServiceRead, | ||
Update: resourceDataFactoryLinkedCustomServiceCreateUpdate, | ||
Delete: resourceDataFactoryLinkedCustomServiceDelete, | ||
|
||
Importer: pluginsdk.ImporterValidatingResourceId(func(id string) error { | ||
_, err := parse.LinkedServiceID(id) | ||
return err | ||
}), | ||
|
||
Timeouts: &pluginsdk.ResourceTimeout{ | ||
Create: pluginsdk.DefaultTimeout(30 * time.Minute), | ||
Read: pluginsdk.DefaultTimeout(5 * time.Minute), | ||
Update: pluginsdk.DefaultTimeout(30 * time.Minute), | ||
Delete: pluginsdk.DefaultTimeout(30 * time.Minute), | ||
}, | ||
|
||
Schema: map[string]*pluginsdk.Schema{ | ||
"name": { | ||
Type: pluginsdk.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
ValidateFunc: validate.LinkedServiceDatasetName, | ||
}, | ||
|
||
"data_factory_id": { | ||
Type: pluginsdk.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
ValidateFunc: validate.DataFactoryID, | ||
}, | ||
|
||
"type": { | ||
Type: pluginsdk.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
}, | ||
|
||
"type_properties_json": { | ||
Type: pluginsdk.TypeString, | ||
Required: true, | ||
StateFunc: utils.NormalizeJson, | ||
DiffSuppressFunc: suppressJsonOrderingDifference, | ||
}, | ||
|
||
"description": { | ||
Type: pluginsdk.TypeString, | ||
Optional: true, | ||
ValidateFunc: validation.StringIsNotEmpty, | ||
}, | ||
|
||
"integration_runtime": { | ||
Type: pluginsdk.TypeList, | ||
Optional: true, | ||
MaxItems: 1, | ||
Elem: &pluginsdk.Resource{ | ||
Schema: map[string]*pluginsdk.Schema{ | ||
"name": { | ||
Type: pluginsdk.TypeString, | ||
Required: true, | ||
ValidateFunc: validation.StringIsNotEmpty, | ||
}, | ||
|
||
"parameters": { | ||
Type: pluginsdk.TypeMap, | ||
Optional: true, | ||
Elem: &pluginsdk.Schema{ | ||
Type: pluginsdk.TypeString, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
|
||
"parameters": { | ||
Type: pluginsdk.TypeMap, | ||
Optional: true, | ||
Elem: &pluginsdk.Schema{ | ||
Type: pluginsdk.TypeString, | ||
}, | ||
}, | ||
|
||
"annotations": { | ||
Type: pluginsdk.TypeList, | ||
Optional: true, | ||
Elem: &pluginsdk.Schema{ | ||
Type: pluginsdk.TypeString, | ||
}, | ||
}, | ||
|
||
"additional_properties": { | ||
Type: pluginsdk.TypeMap, | ||
Optional: true, | ||
Elem: &pluginsdk.Schema{ | ||
Type: pluginsdk.TypeString, | ||
}, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func resourceDataFactoryLinkedCustomServiceCreateUpdate(d *pluginsdk.ResourceData, meta interface{}) error { | ||
client := meta.(*clients.Client).DataFactory.LinkedServiceClient | ||
subscriptionId := meta.(*clients.Client).Account.SubscriptionId | ||
ctx, cancel := timeouts.ForCreateUpdate(meta.(*clients.Client).StopContext, d) | ||
defer cancel() | ||
|
||
dataFactoryId, err := parse.DataFactoryID(d.Get("data_factory_id").(string)) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
id := parse.NewLinkedServiceID(subscriptionId, dataFactoryId.ResourceGroup, dataFactoryId.FactoryName, d.Get("name").(string)) | ||
if d.IsNewResource() { | ||
existing, err := client.Get(ctx, id.ResourceGroup, id.FactoryName, id.Name, "") | ||
if err != nil { | ||
if !utils.ResponseWasNotFound(existing.Response) { | ||
return fmt.Errorf("checking for presence of existing %s: %+v", id, err) | ||
} | ||
} | ||
if !utils.ResponseWasNotFound(existing.Response) { | ||
return tf.ImportAsExistsError("azurerm_data_factory_linked_custom_service", id.ID()) | ||
} | ||
} | ||
|
||
props := map[string]interface{}{ | ||
"type": d.Get("type").(string), | ||
"connectVia": expandDataFactoryLinkedServiceIntegrationRuntimeV2(d.Get("integration_runtime").([]interface{})), | ||
} | ||
|
||
jsonDataStr := fmt.Sprintf(`{ "typeProperties": %s }`, d.Get("type_properties_json").(string)) | ||
if err = json.Unmarshal([]byte(jsonDataStr), &props); err != nil { | ||
return err | ||
} | ||
|
||
if v, ok := d.GetOk("description"); ok { | ||
props["description"] = v.(string) | ||
} | ||
|
||
if v, ok := d.GetOk("parameters"); ok { | ||
props["parameters"] = expandDataFactoryParameters(v.(map[string]interface{})) | ||
} | ||
|
||
if v, ok := d.GetOk("annotations"); ok { | ||
props["annotations"] = v.([]interface{}) | ||
} | ||
|
||
additionalProperties := d.Get("additional_properties").(map[string]interface{}) | ||
for k, v := range additionalProperties { | ||
props[k] = v | ||
} | ||
|
||
jsonData, err := json.Marshal(map[string]interface{}{ | ||
"properties": props, | ||
}) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
linkedService := &datafactory.LinkedServiceResource{} | ||
if err := linkedService.UnmarshalJSON(jsonData); err != nil { | ||
return err | ||
} | ||
|
||
if _, err := client.CreateOrUpdate(ctx, id.ResourceGroup, id.FactoryName, id.Name, *linkedService, ""); err != nil { | ||
return fmt.Errorf("creating/updating %s: %+v", id, err) | ||
} | ||
|
||
d.SetId(id.ID()) | ||
|
||
return resourceDataFactoryLinkedCustomServiceRead(d, meta) | ||
} | ||
|
||
func resourceDataFactoryLinkedCustomServiceRead(d *pluginsdk.ResourceData, meta interface{}) error { | ||
client := meta.(*clients.Client).DataFactory.LinkedServiceClient | ||
subscriptionId := meta.(*clients.Client).Account.SubscriptionId | ||
ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d) | ||
defer cancel() | ||
|
||
id, err := parse.LinkedServiceID(d.Id()) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
resp, err := client.Get(ctx, id.ResourceGroup, id.FactoryName, id.Name, "") | ||
if err != nil { | ||
if utils.ResponseWasNotFound(resp.Response) { | ||
d.SetId("") | ||
return nil | ||
} | ||
|
||
return fmt.Errorf("retrieving %s: %+v", id, err) | ||
} | ||
|
||
d.Set("name", id.Name) | ||
d.Set("data_factory_id", parse.NewDataFactoryID(subscriptionId, id.ResourceGroup, id.FactoryName).ID()) | ||
|
||
byteArr, err := json.Marshal(resp.Properties) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
var m map[string]*json.RawMessage | ||
if err = json.Unmarshal(byteArr, &m); err != nil { | ||
return err | ||
} | ||
|
||
description := "" | ||
if v, ok := m["description"]; ok && v != nil { | ||
if err := json.Unmarshal(*v, &description); err != nil { | ||
return err | ||
} | ||
delete(m, "description") | ||
} | ||
d.Set("description", description) | ||
|
||
t := "" | ||
if v, ok := m["type"]; ok && v != nil { | ||
if err := json.Unmarshal(*v, &t); err != nil { | ||
return err | ||
} | ||
delete(m, "type") | ||
} | ||
d.Set("type", t) | ||
|
||
annotations := make([]interface{}, 0) | ||
if v, ok := m["annotations"]; ok && v != nil { | ||
if err := json.Unmarshal(*v, &annotations); err != nil { | ||
return err | ||
} | ||
delete(m, "annotations") | ||
} | ||
d.Set("annotations", annotations) | ||
|
||
parameters := make(map[string]*datafactory.ParameterSpecification) | ||
if v, ok := m["parameters"]; ok && v != nil { | ||
if err := json.Unmarshal(*v, ¶meters); err != nil { | ||
return err | ||
} | ||
delete(m, "parameters") | ||
} | ||
if err := d.Set("parameters", flattenDataFactoryParameters(parameters)); err != nil { | ||
return fmt.Errorf("setting `parameters`: %+v", err) | ||
} | ||
|
||
var integrationRuntime *datafactory.IntegrationRuntimeReference | ||
if v, ok := m["connectVia"]; ok && v != nil { | ||
integrationRuntime = &datafactory.IntegrationRuntimeReference{} | ||
if err := json.Unmarshal(*v, &integrationRuntime); err != nil { | ||
return err | ||
} | ||
delete(m, "connectVia") | ||
} | ||
if err := d.Set("integration_runtime", flattenDataFactoryLinkedServiceIntegrationRuntimeV2(integrationRuntime)); err != nil { | ||
return fmt.Errorf("setting `integration_runtime`: %+v", err) | ||
} | ||
|
||
delete(m, "typeProperties") | ||
|
||
additionalProperties := make(map[string]interface{}) | ||
for k, v := range m { | ||
additionalProperties[k] = v | ||
} | ||
d.Set("additional_properties", additionalProperties) | ||
|
||
return nil | ||
} | ||
|
||
func resourceDataFactoryLinkedCustomServiceDelete(d *pluginsdk.ResourceData, meta interface{}) error { | ||
client := meta.(*clients.Client).DataFactory.LinkedServiceClient | ||
ctx, cancel := timeouts.ForDelete(meta.(*clients.Client).StopContext, d) | ||
defer cancel() | ||
|
||
id, err := parse.LinkedServiceID(d.Id()) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if _, err := client.Delete(ctx, id.ResourceGroup, id.FactoryName, id.Name); err != nil { | ||
return fmt.Errorf("deleting %s: %+v", id, err) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func expandDataFactoryLinkedServiceIntegrationRuntimeV2(input []interface{}) *datafactory.IntegrationRuntimeReference { | ||
if len(input) == 0 || input[0] == nil { | ||
return nil | ||
} | ||
|
||
v := input[0].(map[string]interface{}) | ||
return &datafactory.IntegrationRuntimeReference{ | ||
ReferenceName: utils.String(v["name"].(string)), | ||
Type: utils.String("IntegrationRuntimeReference"), | ||
Parameters: v["parameters"].(map[string]interface{}), | ||
} | ||
} | ||
|
||
func flattenDataFactoryLinkedServiceIntegrationRuntimeV2(input *datafactory.IntegrationRuntimeReference) []interface{} { | ||
if input == nil { | ||
return []interface{}{} | ||
} | ||
|
||
name := "" | ||
if input.ReferenceName != nil { | ||
name = *input.ReferenceName | ||
} | ||
|
||
return []interface{}{ | ||
map[string]interface{}{ | ||
"name": name, | ||
"parameters": input.Parameters, | ||
}, | ||
} | ||
} |
Oops, something went wrong.