func resourceAwsEfsMountTargetRead(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).efsconn
	resp, err := conn.DescribeMountTargets(&efs.DescribeMountTargetsInput{
		MountTargetId: aws.String(d.Id()),
	})
	if err != nil {
		return err
	}

	if len(resp.MountTargets) < 1 {
		return fmt.Errorf("EFS mount target %q not found", d.Id())
	}

	mt := resp.MountTargets[0]

	log.Printf("[DEBUG] Found EFS mount target: %#v", mt)

	d.SetId(*mt.MountTargetId)
	d.Set("file_system_id", *mt.FileSystemId)
	d.Set("ip_address", *mt.IpAddress)
	d.Set("subnet_id", *mt.SubnetId)
	d.Set("network_interface_id", *mt.NetworkInterfaceId)

	sgResp, err := conn.DescribeMountTargetSecurityGroups(&efs.DescribeMountTargetSecurityGroupsInput{
		MountTargetId: aws.String(d.Id()),
	})
	if err != nil {
		return err
	}

	d.Set("security_groups", schema.NewSet(schema.HashString, flattenStringList(sgResp.SecurityGroups)))

	return nil
}
func flattenDSConnectSettings(
	customerDnsIps []*string,
	s *directoryservice.DirectoryConnectSettingsDescription) []map[string]interface{} {
	if s == nil {
		return nil
	}

	settings := make(map[string]interface{}, 0)

	settings["customer_dns_ips"] = schema.NewSet(schema.HashString, flattenStringList(customerDnsIps))
	settings["connect_ips"] = schema.NewSet(schema.HashString, flattenStringList(s.ConnectIps))
	settings["customer_username"] = *s.CustomerUserName
	settings["subnet_ids"] = schema.NewSet(schema.HashString, flattenStringList(s.SubnetIds))
	settings["vpc_id"] = *s.VpcId

	return []map[string]interface{}{settings}
}
// resourceAzureSqlDatabaseServerFirewallRuleUpdate does all the necessary API
// calls to update the state of the SQL Database Server Firewall Rule on Azure.
func resourceAzureSqlDatabaseServerFirewallRuleUpdate(d *schema.ResourceData, meta interface{}) error {
	sqlClient := meta.(*Client).sqlClient

	var found bool
	name := d.Get("name").(string)
	updateParams := sql.FirewallRuleUpdateParams{
		Name:           name,
		StartIPAddress: d.Get("start_ip").(string),
		EndIPAddress:   d.Get("end_ip").(string),
	}

	// for each of the Database Servers our rules concerns; issue the update:
	remaining := schema.NewSet(schema.HashString, nil)
	for _, srv := range d.Get("database_server_names").(*schema.Set).List() {
		serverName := srv.(string)

		log.Printf("[INFO] Issuing Azure Database Server Firewall Rule list for Database Server %q: %s.", name, serverName)
		rules, err := sqlClient.ListFirewallRules(serverName)
		if err != nil {
			if strings.Contains(err.Error(), "does not exist") {
				// it means that the database server this rule belonged to has
				// been deleted in the meantime.
				continue
			} else {
				return fmt.Errorf("Error getting Azure Firewall Rules for Database Server %q: %s", serverName, err)
			}

		}

		// look for our rule:
		for _, rule := range rules.FirewallRules {
			if rule.Name == name {
				// take note of the fact that this Database Server still has
				// this rule:
				found = true
				remaining.Add(serverName)

				// go ahead and update the rule:
				log.Printf("[INFO] Issuing update of Azure Database Server Firewall Rule %q in Server %q.", name, serverName)
				if err := sqlClient.UpdateFirewallRule(serverName, name, updateParams); err != nil {
					return fmt.Errorf("Error updating Azure Database Server Firewall Rule %q for Server %q: %s", name, serverName, err)
				}

				break
			}
		}
	}

	// check to see if the rule is still exists on any of the servers:
	if !found {
		d.SetId("")
		return nil
	}

	// else; update the list with the remaining Servers:
	d.Set("database_server_names", remaining)
	return nil
}
func flattenDSVpcSettings(
	s *directoryservice.DirectoryVpcSettingsDescription) []map[string]interface{} {
	settings := make(map[string]interface{}, 0)

	if s == nil {
		return nil
	}

	settings["subnet_ids"] = schema.NewSet(schema.HashString, flattenStringList(s.SubnetIds))
	settings["vpc_id"] = *s.VpcId

	return []map[string]interface{}{settings}
}
func resourceAwsDirectoryServiceDirectoryRead(d *schema.ResourceData, meta interface{}) error {
	dsconn := meta.(*AWSClient).dsconn

	input := directoryservice.DescribeDirectoriesInput{
		DirectoryIds: []*string{aws.String(d.Id())},
	}
	out, err := dsconn.DescribeDirectories(&input)
	if err != nil {
		return err
	}

	dir := out.DirectoryDescriptions[0]
	log.Printf("[DEBUG] Received DS directory: %s", *dir)

	d.Set("access_url", *dir.AccessUrl)
	d.Set("alias", *dir.Alias)
	if dir.Description != nil {
		d.Set("description", *dir.Description)
	}

	if *dir.Type == "ADConnector" {
		d.Set("dns_ip_addresses", schema.NewSet(schema.HashString, flattenStringList(dir.ConnectSettings.ConnectIps)))
	} else {
		d.Set("dns_ip_addresses", schema.NewSet(schema.HashString, flattenStringList(dir.DnsIpAddrs)))
	}
	d.Set("name", *dir.Name)
	if dir.ShortName != nil {
		d.Set("short_name", *dir.ShortName)
	}
	if dir.Size != nil {
		d.Set("size", *dir.Size)
	}
	d.Set("type", *dir.Type)
	d.Set("vpc_settings", flattenDSVpcSettings(dir.VpcSettings))
	d.Set("connect_settings", flattenDSConnectSettings(dir.DnsIpAddrs, dir.ConnectSettings))
	d.Set("enable_sso", *dir.SsoEnabled)

	return nil
}
// resourceAzureSecurityGroupRuleRead does all the necessary API calls to
// read the state of a network security group ruke off Azure.
func resourceAzureSecurityGroupRuleRead(d *schema.ResourceData, meta interface{}) error {
	azureClient := meta.(*Client)
	secGroupClient := azureClient.secGroupClient

	var found bool
	name := d.Get("name").(string)

	secGroups := d.Get("security_group_names").(*schema.Set).List()
	remaining := schema.NewSet(schema.HashString, nil)

	// for each of our security groups; check for our rule:
	for _, sg := range secGroups {
		secGroupName := sg.(string)

		// get info on the network security group and check its rules for this one:
		log.Printf("[INFO] Sending Azure network security group rule query for security group %s.", secGroupName)
		secgroup, err := secGroupClient.GetNetworkSecurityGroup(secGroupName)
		if err != nil {
			if !management.IsResourceNotFoundError(err) {
				return fmt.Errorf("Error issuing network security group rules query for security group %q: %s", secGroupName, err)
			} else {
				// it meants that the network security group this rule belonged to has
				// been deleted; so we skip this iteration:
				continue
			}
		}

		// find our security rule:
		for _, rule := range secgroup.Rules {
			if rule.Name == name {
				// note the fact that this rule still apllies to this security group:
				found = true
				remaining.Add(secGroupName)

				break
			}
		}
	}

	// check to see if there is any security group still having this rule:
	if !found {
		d.SetId("")
		return nil
	}

	// now; we must update the set of security groups still having this rule:
	d.Set("security_group_names", remaining)
	return nil
}
// resourceAzureSqlDatabaseServerFirewallRuleRead does all the necessary API
// calls to read the state of the SQL Database Server Firewall Rule on Azure.
func resourceAzureSqlDatabaseServerFirewallRuleRead(d *schema.ResourceData, meta interface{}) error {
	sqlClient := meta.(*Client).sqlClient

	name := d.Get("name").(string)
	remaining := schema.NewSet(schema.HashString, nil)

	// for each of our servers; check to see if the rule is still present:
	var found bool
	for _, srv := range d.Get("database_server_names").(*schema.Set).List() {
		serverName := srv.(string)

		log.Printf("[INFO] Sending Azure Database Server Firewall Rule list query for server %q.", serverName)
		rules, err := sqlClient.ListFirewallRules(serverName)
		if err != nil {
			if strings.Contains(err.Error(), "does not exist") {
				// it means that the database server this rule belonged to has
				// been deleted in the meantime.
				continue
			} else {
				return fmt.Errorf("Error getting Azure Firewall Rules for Database Server %q: %s", serverName, err)
			}

		}

		// look for our rule:
		for _, rule := range rules.FirewallRules {
			if rule.Name == name {
				found = true
				remaining.Add(serverName)

				break
			}
		}
	}

	// check to see if there is still any Database Server still having this rule:
	if !found {
		d.SetId("")
		return nil
	}

	// else; update the list of Database Servers still having this rule:
	d.Set("database_server_names", remaining)
	return nil
}
// resourceAzureSecurityGroupRuleUpdate does all the necessary API calls to
// update the state of a network security group rule off Azure.
func resourceAzureSecurityGroupRuleUpdate(d *schema.ResourceData, meta interface{}) error {
	azureClient := meta.(*Client)
	mgmtClient := azureClient.mgmtClient
	secGroupClient := azureClient.secGroupClient

	azureClient.secGroupMutex.Lock()
	defer azureClient.secGroupMutex.Unlock()

	var found bool
	name := d.Get("name").(string)
	newRule := netsecgroup.RuleRequest{
		Name:                     d.Get("name").(string),
		Type:                     netsecgroup.RuleType(d.Get("type").(string)),
		Priority:                 d.Get("priority").(int),
		Action:                   netsecgroup.RuleAction(d.Get("action").(string)),
		SourceAddressPrefix:      d.Get("source_address_prefix").(string),
		SourcePortRange:          d.Get("source_port_range").(string),
		DestinationAddressPrefix: d.Get("destination_address_prefix").(string),
		DestinationPortRange:     d.Get("destination_port_range").(string),
		Protocol:                 netsecgroup.RuleProtocol(d.Get("protocol").(string)),
	}

	// iterate over all the security groups that should have this rule and
	// update it per security group:
	remaining := schema.NewSet(schema.HashString, nil)
	secGroupNames := d.Get("security_group_names").(*schema.Set).List()
	for _, sg := range secGroupNames {
		secGroupName := sg.(string)

		// get info on the network security group and check its rules for this one:
		log.Printf("[INFO] Sending Azure network security group rule query for security group %q.", secGroupName)
		secgroup, err := secGroupClient.GetNetworkSecurityGroup(secGroupName)
		if err != nil {
			if !management.IsResourceNotFoundError(err) {
				return fmt.Errorf("Error issuing network security group rules query: %s", err)
			} else {
				// it meants that the network security group this rule belonged to has
				// been deleted; so we skip this iteration:
				continue
			}
		}

		// try and find our security group rule:
		for _, rule := range secgroup.Rules {
			if rule.Name == name {
				// note the fact that this rule still applies to this security group:
				found = true
				remaining.Add(secGroupName)

				// and go ahead and update it:
				log.Printf("[INFO] Sending Azure network security group rule update request for security group %q.", secGroupName)
				reqID, err := secGroupClient.SetNetworkSecurityGroupRule(
					secGroupName,
					newRule,
				)
				if err != nil {
					return fmt.Errorf("Error sending Azure network security group rule update request for security group %q: %s", secGroupName, err)
				}
				err = mgmtClient.WaitForOperation(reqID, nil)
				if err != nil {
					return fmt.Errorf("Error updating Azure network security group rule for security group %q: %s", secGroupName, err)
				}

				break
			}
		}
	}

	// check to see if there is any security group still having this rule:
	if !found {
		d.SetId("")
		return nil
	}

	// here; we must update the set of security groups still having this rule:
	d.Set("security_group_names", remaining)

	return nil
}
func TestExpandIPPerms(t *testing.T) {
	hash := schema.HashString

	expanded := []interface{}{
		map[string]interface{}{
			"protocol":    "icmp",
			"from_port":   1,
			"to_port":     -1,
			"cidr_blocks": []interface{}{"0.0.0.0/0"},
			"security_groups": schema.NewSet(hash, []interface{}{
				"sg-11111",
				"foo/sg-22222",
			}),
		},
		map[string]interface{}{
			"protocol":  "icmp",
			"from_port": 1,
			"to_port":   -1,
			"self":      true,
		},
	}
	group := &ec2.SecurityGroup{
		GroupId: aws.String("foo"),
		VpcId:   aws.String("bar"),
	}
	perms, err := expandIPPerms(group, expanded)
	if err != nil {
		t.Fatalf("error expanding perms: %v", err)
	}

	expected := []ec2.IpPermission{
		ec2.IpPermission{
			IpProtocol: aws.String("icmp"),
			FromPort:   aws.Int64(int64(1)),
			ToPort:     aws.Int64(int64(-1)),
			IpRanges:   []*ec2.IpRange{&ec2.IpRange{CidrIp: aws.String("0.0.0.0/0")}},
			UserIdGroupPairs: []*ec2.UserIdGroupPair{
				&ec2.UserIdGroupPair{
					UserId:  aws.String("foo"),
					GroupId: aws.String("sg-22222"),
				},
				&ec2.UserIdGroupPair{
					GroupId: aws.String("sg-22222"),
				},
			},
		},
		ec2.IpPermission{
			IpProtocol: aws.String("icmp"),
			FromPort:   aws.Int64(int64(1)),
			ToPort:     aws.Int64(int64(-1)),
			UserIdGroupPairs: []*ec2.UserIdGroupPair{
				&ec2.UserIdGroupPair{
					UserId: aws.String("foo"),
				},
			},
		},
	}

	exp := expected[0]
	perm := perms[0]

	if *exp.FromPort != *perm.FromPort {
		t.Fatalf(
			"Got:\n\n%#v\n\nExpected:\n\n%#v\n",
			*perm.FromPort,
			*exp.FromPort)
	}

	if *exp.IpRanges[0].CidrIp != *perm.IpRanges[0].CidrIp {
		t.Fatalf(
			"Got:\n\n%#v\n\nExpected:\n\n%#v\n",
			*perm.IpRanges[0].CidrIp,
			*exp.IpRanges[0].CidrIp)
	}

	if *exp.UserIdGroupPairs[0].UserId != *perm.UserIdGroupPairs[0].UserId {
		t.Fatalf(
			"Got:\n\n%#v\n\nExpected:\n\n%#v\n",
			*perm.UserIdGroupPairs[0].UserId,
			*exp.UserIdGroupPairs[0].UserId)
	}

}
func TestExpandIPPerms_NegOneProtocol(t *testing.T) {
	hash := schema.HashString

	expanded := []interface{}{
		map[string]interface{}{
			"protocol":    "-1",
			"from_port":   0,
			"to_port":     0,
			"cidr_blocks": []interface{}{"0.0.0.0/0"},
			"security_groups": schema.NewSet(hash, []interface{}{
				"sg-11111",
				"foo/sg-22222",
			}),
		},
	}
	group := &ec2.SecurityGroup{
		GroupId: aws.String("foo"),
		VpcId:   aws.String("bar"),
	}

	perms, err := expandIPPerms(group, expanded)
	if err != nil {
		t.Fatalf("error expanding perms: %v", err)
	}

	expected := []ec2.IpPermission{
		ec2.IpPermission{
			IpProtocol: aws.String("-1"),
			FromPort:   aws.Int64(int64(0)),
			ToPort:     aws.Int64(int64(0)),
			IpRanges:   []*ec2.IpRange{&ec2.IpRange{CidrIp: aws.String("0.0.0.0/0")}},
			UserIdGroupPairs: []*ec2.UserIdGroupPair{
				&ec2.UserIdGroupPair{
					UserId:  aws.String("foo"),
					GroupId: aws.String("sg-22222"),
				},
				&ec2.UserIdGroupPair{
					GroupId: aws.String("sg-22222"),
				},
			},
		},
	}

	exp := expected[0]
	perm := perms[0]

	if *exp.FromPort != *perm.FromPort {
		t.Fatalf(
			"Got:\n\n%#v\n\nExpected:\n\n%#v\n",
			*perm.FromPort,
			*exp.FromPort)
	}

	if *exp.IpRanges[0].CidrIp != *perm.IpRanges[0].CidrIp {
		t.Fatalf(
			"Got:\n\n%#v\n\nExpected:\n\n%#v\n",
			*perm.IpRanges[0].CidrIp,
			*exp.IpRanges[0].CidrIp)
	}

	if *exp.UserIdGroupPairs[0].UserId != *perm.UserIdGroupPairs[0].UserId {
		t.Fatalf(
			"Got:\n\n%#v\n\nExpected:\n\n%#v\n",
			*perm.UserIdGroupPairs[0].UserId,
			*exp.UserIdGroupPairs[0].UserId)
	}

	// Now test the error case. This *should* error when either from_port
	// or to_port is not zero, but protocol is "-1".
	errorCase := []interface{}{
		map[string]interface{}{
			"protocol":    "-1",
			"from_port":   0,
			"to_port":     65535,
			"cidr_blocks": []interface{}{"0.0.0.0/0"},
			"security_groups": schema.NewSet(hash, []interface{}{
				"sg-11111",
				"foo/sg-22222",
			}),
		},
	}
	securityGroups := &ec2.SecurityGroup{
		GroupId: aws.String("foo"),
		VpcId:   aws.String("bar"),
	}

	_, expandErr := expandIPPerms(securityGroups, errorCase)
	if expandErr == nil {
		t.Fatal("expandIPPerms should have errored!")
	}
}
func resourceAwsCloudFormationStackRead(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).cfconn
	stackName := d.Get("name").(string)

	input := &cloudformation.DescribeStacksInput{
		StackName: aws.String(stackName),
	}
	resp, err := conn.DescribeStacks(input)
	if err != nil {
		return err
	}

	stacks := resp.Stacks
	if len(stacks) < 1 {
		log.Printf("[DEBUG] Removing CloudFormation stack %s as it's already gone", d.Id())
		d.SetId("")
		return nil
	}
	for _, s := range stacks {
		if *s.StackId == d.Id() && *s.StackStatus == "DELETE_COMPLETE" {
			log.Printf("[DEBUG] Removing CloudFormation stack %s"+
				" as it has been already deleted", d.Id())
			d.SetId("")
			return nil
		}
	}

	tInput := cloudformation.GetTemplateInput{
		StackName: aws.String(stackName),
	}
	out, err := conn.GetTemplate(&tInput)
	if err != nil {
		return err
	}

	d.Set("template_body", normalizeJson(*out.TemplateBody))

	stack := stacks[0]
	log.Printf("[DEBUG] Received CloudFormation stack: %s", stack)

	d.Set("name", stack.StackName)
	d.Set("arn", stack.StackId)

	if stack.TimeoutInMinutes != nil {
		d.Set("timeout_in_minutes", int(*stack.TimeoutInMinutes))
	}
	if stack.Description != nil {
		d.Set("description", stack.Description)
	}
	if stack.DisableRollback != nil {
		d.Set("disable_rollback", stack.DisableRollback)
	}
	if len(stack.NotificationARNs) > 0 {
		err = d.Set("notification_arns", schema.NewSet(schema.HashString, flattenStringList(stack.NotificationARNs)))
		if err != nil {
			return err
		}
	}

	originalParams := d.Get("parameters").(map[string]interface{})
	err = d.Set("parameters", flattenCloudFormationParameters(stack.Parameters, originalParams))
	if err != nil {
		return err
	}

	err = d.Set("tags", flattenCloudFormationTags(stack.Tags))
	if err != nil {
		return err
	}

	err = d.Set("outputs", flattenCloudFormationOutputs(stack.Outputs))
	if err != nil {
		return err
	}

	if len(stack.Capabilities) > 0 {
		err = d.Set("capabilities", schema.NewSet(schema.HashString, flattenStringList(stack.Capabilities)))
		if err != nil {
			return err
		}
	}

	return nil
}
func resourceComputeInstanceRead(d *schema.ResourceData, meta interface{}) error {
	config := meta.(*Config)

	id := d.Id()
	instance, err := getInstance(config, d)
	if err != nil {
		if strings.Contains(err.Error(), "no longer exists") {
			log.Printf("[WARN] Google Compute Instance (%s) not found", id)
			return nil
		}
		return err
	}

	// Synch metadata
	md := instance.Metadata

	_md := MetadataFormatSchema(d.Get("metadata").(map[string]interface{}), md)
	delete(_md, "startup-script")

	if script, scriptExists := d.GetOk("metadata_startup_script"); scriptExists {
		d.Set("metadata_startup_script", script)
	}

	if err = d.Set("metadata", _md); err != nil {
		return fmt.Errorf("Error setting metadata: %s", err)
	}

	d.Set("can_ip_forward", instance.CanIpForward)

	// Set the service accounts
	serviceAccounts := make([]map[string]interface{}, 0, 1)
	for _, serviceAccount := range instance.ServiceAccounts {
		scopes := make([]interface{}, len(serviceAccount.Scopes))
		for i, scope := range serviceAccount.Scopes {
			scopes[i] = scope
		}
		serviceAccounts = append(serviceAccounts, map[string]interface{}{
			"email":  serviceAccount.Email,
			"scopes": schema.NewSet(stringScopeHashcode, scopes),
		})
	}
	d.Set("service_account", serviceAccounts)

	networksCount := d.Get("network.#").(int)
	networkInterfacesCount := d.Get("network_interface.#").(int)

	if networksCount > 0 && networkInterfacesCount > 0 {
		return fmt.Errorf("Error: cannot define both networks and network_interfaces.")
	}
	if networksCount == 0 && networkInterfacesCount == 0 {
		return fmt.Errorf("Error: Must define at least one network_interface.")
	}

	// Set the networks
	// Use the first external IP found for the default connection info.
	externalIP := ""
	internalIP := ""
	networks := make([]map[string]interface{}, 0, 1)
	if networksCount > 0 {
		// TODO: Remove this when realizing deprecation of .network
		for i, iface := range instance.NetworkInterfaces {
			var natIP string
			for _, config := range iface.AccessConfigs {
				if config.Type == "ONE_TO_ONE_NAT" {
					natIP = config.NatIP
					break
				}
			}

			if externalIP == "" && natIP != "" {
				externalIP = natIP
			}

			network := make(map[string]interface{})
			network["name"] = iface.Name
			network["external_address"] = natIP
			network["internal_address"] = iface.NetworkIP
			network["source"] = d.Get(fmt.Sprintf("network.%d.source", i))
			networks = append(networks, network)
		}
	}
	d.Set("network", networks)

	networkInterfaces := make([]map[string]interface{}, 0, 1)
	if networkInterfacesCount > 0 {
		for i, iface := range instance.NetworkInterfaces {
			// The first non-empty ip is left in natIP
			var natIP string
			accessConfigs := make(
				[]map[string]interface{}, 0, len(iface.AccessConfigs))
			for j, config := range iface.AccessConfigs {
				accessConfigs = append(accessConfigs, map[string]interface{}{
					"nat_ip":          d.Get(fmt.Sprintf("network_interface.%d.access_config.%d.nat_ip", i, j)),
					"assigned_nat_ip": config.NatIP,
				})

				if natIP == "" {
					natIP = config.NatIP
				}
			}

			if externalIP == "" {
				externalIP = natIP
			}

			if internalIP == "" {
				internalIP = iface.NetworkIP
			}

			networkInterfaces = append(networkInterfaces, map[string]interface{}{
				"name":          iface.Name,
				"address":       iface.NetworkIP,
				"network":       d.Get(fmt.Sprintf("network_interface.%d.network", i)),
				"access_config": accessConfigs,
			})
		}
	}
	d.Set("network_interface", networkInterfaces)

	// Fall back on internal ip if there is no external ip.  This makes sense in the situation where
	// terraform is being used on a cloud instance and can therefore access the instances it creates
	// via their internal ips.
	sshIP := externalIP
	if sshIP == "" {
		sshIP = internalIP
	}

	// Initialize the connection info
	d.SetConnInfo(map[string]string{
		"type": "ssh",
		"host": sshIP,
	})

	// Set the metadata fingerprint if there is one.
	if instance.Metadata != nil {
		d.Set("metadata_fingerprint", instance.Metadata.Fingerprint)
	}

	// Set the tags fingerprint if there is one.
	if instance.Tags != nil {
		d.Set("tags_fingerprint", instance.Tags.Fingerprint)
	}

	d.Set("self_link", instance.SelfLink)
	d.SetId(instance.Name)

	return nil
}