func createNetworkACLRules(d *schema.ResourceData, meta interface{}, rules *schema.Set, nrs *schema.Set) error {
	var errs *multierror.Error

	var wg sync.WaitGroup
	wg.Add(nrs.Len())

	sem := make(chan struct{}, d.Get("parallelism").(int))
	for _, rule := range nrs.List() {
		// Put in a tiny sleep here to avoid DoS'ing the API
		time.Sleep(500 * time.Millisecond)

		go func(rule map[string]interface{}) {
			defer wg.Done()
			sem <- struct{}{}

			// Create a single rule
			err := createNetworkACLRule(d, meta, rule)

			// If we have at least one UUID, we need to save the rule
			if len(rule["uuids"].(map[string]interface{})) > 0 {
				rules.Add(rule)
			}

			if err != nil {
				errs = multierror.Append(errs, err)
			}

			<-sem
		}(rule.(map[string]interface{}))
	}

	wg.Wait()

	return errs.ErrorOrNil()
}
func resourceAwsNetworkInterfaceDetach(oa *schema.Set, meta interface{}, eniId string) error {
	// if there was an old attachment, remove it
	if oa != nil && len(oa.List()) > 0 {
		old_attachment := oa.List()[0].(map[string]interface{})
		detach_request := &ec2.DetachNetworkInterfaceInput{
			AttachmentId: aws.String(old_attachment["attachment_id"].(string)),
			Force:        aws.Bool(true),
		}
		conn := meta.(*AWSClient).ec2conn
		_, detach_err := conn.DetachNetworkInterface(detach_request)
		if detach_err != nil {
			return fmt.Errorf("Error detaching ENI: %s", detach_err)
		}

		log.Printf("[DEBUG] Waiting for ENI (%s) to become dettached", eniId)
		stateConf := &resource.StateChangeConf{
			Pending: []string{"true"},
			Target:  []string{"false"},
			Refresh: networkInterfaceAttachmentRefreshFunc(conn, eniId),
			Timeout: 10 * time.Minute,
		}
		if _, err := stateConf.WaitForState(); err != nil {
			return fmt.Errorf(
				"Error waiting for ENI (%s) to become dettached: %s", eniId, err)
		}
	}

	return nil
}
func portSetToDockerPorts(ports *schema.Set) (map[dc.Port]struct{}, map[dc.Port][]dc.PortBinding) {
	retExposedPorts := map[dc.Port]struct{}{}
	retPortBindings := map[dc.Port][]dc.PortBinding{}

	for _, portInt := range ports.List() {
		port := portInt.(map[string]interface{})
		internal := port["internal"].(int)
		protocol := port["protocol"].(string)

		exposedPort := dc.Port(strconv.Itoa(internal) + "/" + protocol)
		retExposedPorts[exposedPort] = struct{}{}

		external, extOk := port["external"].(int)
		ip, ipOk := port["ip"].(string)

		if extOk {
			portBinding := dc.PortBinding{
				HostPort: strconv.Itoa(external),
			}
			if ipOk {
				portBinding.HostIP = ip
			}
			retPortBindings[exposedPort] = append(retPortBindings[exposedPort], portBinding)
		}
	}

	return retExposedPorts, retPortBindings
}
// Helper function used by originHash to get a composite hash for all
// aws_cloudfront_distribution custom_header attributes.
func customHeadersHash(s *schema.Set) int {
	var buf bytes.Buffer
	for _, v := range s.List() {
		buf.WriteString(fmt.Sprintf("%d-", originCustomHeaderHash(v)))
	}
	return hashcode.String(buf.String())
}
예제 #5
0
// buildEC2CustomFilterList takes the set value extracted from a schema
// attribute conforming to the schema returned by ec2CustomFiltersSchema,
// and transforms it into a []*ec2.Filter representing the same filter
// expressions which is ready to pass into the "Filters" attribute on most
// of the "Describe..." functions in the EC2 API.
//
// This function is intended only to be used in conjunction with
// ec2CustomFitlersSchema. See the docs on that function for more details
// on the configuration pattern this is intended to support.
func buildEC2CustomFilterList(filterSet *schema.Set) []*ec2.Filter {
	if filterSet == nil {
		return []*ec2.Filter{}
	}

	customFilters := filterSet.List()
	filters := make([]*ec2.Filter, len(customFilters))

	for filterIdx, customFilterI := range customFilters {
		customFilterMapI := customFilterI.(map[string]interface{})
		name := customFilterMapI["name"].(string)
		valuesI := customFilterMapI["values"].(*schema.Set).List()
		values := make([]*string, len(valuesI))
		for valueIdx, valueI := range valuesI {
			values[valueIdx] = aws.String(valueI.(string))
		}

		filters[filterIdx] = &ec2.Filter{
			Name:   &name,
			Values: values,
		}
	}

	return filters
}
func deletePortForwards(d *schema.ResourceData, meta interface{}, forwards *schema.Set, ors *schema.Set) error {
	var errs *multierror.Error

	var wg sync.WaitGroup
	wg.Add(ors.Len())

	sem := make(chan struct{}, 10)
	for _, forward := range ors.List() {
		// Put a sleep here to avoid DoS'ing the API
		time.Sleep(500 * time.Millisecond)

		go func(forward map[string]interface{}) {
			defer wg.Done()
			sem <- struct{}{}

			// Delete a single forward
			err := deletePortForward(d, meta, forward)

			// If we have a UUID, we need to save the forward
			if forward["uuid"].(string) != "" {
				forwards.Add(forward)
			}

			if err != nil {
				errs = multierror.Append(errs, err)
			}

			<-sem
		}(forward.(map[string]interface{}))
	}

	wg.Wait()

	return errs.ErrorOrNil()
}
//Convert schema.Set to a slice of strings
func setToStringSlice(s *schema.Set) []string {
	list := make([]string, s.Len())
	for i, v := range s.List() {
		list[i] = v.(string)
	}
	return list
}
func volumeSetToDockerVolumes(volumes *schema.Set) (map[string]struct{}, []string, []string, error) {
	retVolumeMap := map[string]struct{}{}
	retHostConfigBinds := []string{}
	retVolumeFromContainers := []string{}

	for _, volumeInt := range volumes.List() {
		volume := volumeInt.(map[string]interface{})
		fromContainer := volume["from_container"].(string)
		containerPath := volume["container_path"].(string)
		hostPath := volume["host_path"].(string)
		readOnly := volume["read_only"].(bool)

		switch {
		case len(fromContainer) == 0 && len(containerPath) == 0:
			return retVolumeMap, retHostConfigBinds, retVolumeFromContainers, errors.New("Volume entry without container path or source container")
		case len(fromContainer) != 0 && len(containerPath) != 0:
			return retVolumeMap, retHostConfigBinds, retVolumeFromContainers, errors.New("Both a container and a path specified in a volume entry")
		case len(fromContainer) != 0:
			retVolumeFromContainers = append(retVolumeFromContainers, fromContainer)
		case len(hostPath) != 0:
			readWrite := "rw"
			if readOnly {
				readWrite = "ro"
			}
			retVolumeMap[containerPath] = struct{}{}
			retHostConfigBinds = append(retHostConfigBinds, hostPath+":"+containerPath+":"+readWrite)
		default:
			retVolumeMap[containerPath] = struct{}{}
		}
	}

	return retVolumeMap, retHostConfigBinds, retVolumeFromContainers, nil
}
예제 #9
0
func makeAwsStringSet(in *schema.Set) []*string {
	inList := in.List()
	ret := make([]*string, len(inList), len(inList))
	for i := 0; i < len(ret); i++ {
		ret[i] = aws.String(inList[i].(string))
	}
	return ret
}
func createChildHealthCheckList(s *schema.Set) (nl []*string) {
	l := s.List()
	for _, n := range l {
		nl = append(nl, aws.String(n.(string)))
	}

	return nl
}
func convertSetToList(s *schema.Set) (nl []*string) {
	l := s.List()
	for _, n := range l {
		nl = append(nl, aws.String(n.(string)))
	}

	return nl
}
// dataSourceGoogleIamPolicyMembers converts a set of members in a binding
// (a member is a principal, usually an e-mail address) into an array of
// string.
func dataSourceGoogleIamPolicyMembers(d *schema.Set) []string {
	var members []string
	members = make([]string, d.Len())

	for i, v := range d.List() {
		members[i] = v.(string)
	}
	return members
}
예제 #13
0
func setToMapByKey(s *schema.Set, key string) map[string]interface{} {
	result := make(map[string]interface{})
	for _, rawData := range s.List() {
		data := rawData.(map[string]interface{})
		result[data[key].(string)] = data
	}

	return result
}
func stringSetToStringSlice(stringSet *schema.Set) []string {
	ret := []string{}
	if stringSet == nil {
		return ret
	}
	for _, envVal := range stringSet.List() {
		ret = append(ret, envVal.(string))
	}
	return ret
}
func expandAliases(as *schema.Set) *cloudfront.Aliases {
	s := as.List()
	var aliases cloudfront.Aliases
	if len(s) > 0 {
		aliases.Quantity = aws.Int64(int64(len(s)))
		aliases.Items = expandStringList(s)
	} else {
		aliases.Quantity = aws.Int64(0)
	}
	return &aliases
}
func expandOrigins(s *schema.Set) *cloudfront.Origins {
	qty := 0
	items := []*cloudfront.Origin{}
	for _, v := range s.List() {
		items = append(items, expandOrigin(v.(map[string]interface{})))
		qty++
	}
	return &cloudfront.Origins{
		Quantity: aws.Int64(int64(qty)),
		Items:    items,
	}
}
func expandCacheBehaviors(s *schema.Set) *cloudfront.CacheBehaviors {
	var qty int64
	var items []*cloudfront.CacheBehavior
	for _, v := range s.List() {
		items = append(items, expandCacheBehavior(v.(map[string]interface{})))
		qty++
	}
	return &cloudfront.CacheBehaviors{
		Quantity: aws.Int64(qty),
		Items:    items,
	}
}
func extraHostsSetToDockerExtraHosts(extraHosts *schema.Set) []string {
	retExtraHosts := []string{}

	for _, hostInt := range extraHosts.List() {
		host := hostInt.(map[string]interface{})
		ip := host["ip"].(string)
		hostname := host["host"].(string)
		retExtraHosts = append(retExtraHosts, hostname+":"+ip)
	}

	return retExtraHosts
}
예제 #19
0
// buildSystemInterface builds a cobblerclient.Interface out of the Terraform attributes
func buildSystemInterfaces(systemInterfaces *schema.Set) cobbler.Interfaces {
	interfaces := make(cobbler.Interfaces)
	rawInterfaces := systemInterfaces.List()
	for _, rawInterface := range rawInterfaces {
		rawInterfaceMap := rawInterface.(map[string]interface{})

		cnames := []string{}
		for _, i := range rawInterfaceMap["cnames"].([]interface{}) {
			cnames = append(cnames, i.(string))
		}

		ipv6Secondaries := []string{}
		for _, i := range rawInterfaceMap["ipv6_secondaries"].([]interface{}) {
			ipv6Secondaries = append(ipv6Secondaries, i.(string))
		}

		ipv6StaticRoutes := []string{}
		for _, i := range rawInterfaceMap["ipv6_static_routes"].([]interface{}) {
			ipv6StaticRoutes = append(ipv6StaticRoutes, i.(string))
		}

		staticRoutes := []string{}
		for _, i := range rawInterfaceMap["static_routes"].([]interface{}) {
			staticRoutes = append(staticRoutes, i.(string))
		}

		interfaceName := rawInterfaceMap["name"].(string)
		interfaces[interfaceName] = cobbler.Interface{
			CNAMEs:             cnames,
			DHCPTag:            rawInterfaceMap["dhcp_tag"].(string),
			DNSName:            rawInterfaceMap["dns_name"].(string),
			BondingOpts:        rawInterfaceMap["bonding_opts"].(string),
			BridgeOpts:         rawInterfaceMap["bridge_opts"].(string),
			Gateway:            rawInterfaceMap["gateway"].(string),
			InterfaceType:      rawInterfaceMap["interface_type"].(string),
			InterfaceMaster:    rawInterfaceMap["interface_master"].(string),
			IPAddress:          rawInterfaceMap["ip_address"].(string),
			IPv6Address:        rawInterfaceMap["ipv6_address"].(string),
			IPv6Secondaries:    ipv6Secondaries,
			IPv6MTU:            rawInterfaceMap["ipv6_mtu"].(string),
			IPv6StaticRoutes:   ipv6StaticRoutes,
			IPv6DefaultGateway: rawInterfaceMap["ipv6_default_gateway"].(string),
			MACAddress:         rawInterfaceMap["mac_address"].(string),
			Management:         rawInterfaceMap["management"].(bool),
			Netmask:            rawInterfaceMap["netmask"].(string),
			Static:             rawInterfaceMap["static"].(bool),
			StaticRoutes:       staticRoutes,
			VirtBridge:         rawInterfaceMap["virt_bridge"].(string),
		}
	}

	return interfaces
}
func expandCustomErrorResponses(s *schema.Set) *cloudfront.CustomErrorResponses {
	qty := 0
	items := []*cloudfront.CustomErrorResponse{}
	for _, v := range s.List() {
		items = append(items, expandCustomErrorResponse(v.(map[string]interface{})))
		qty++
	}
	return &cloudfront.CustomErrorResponses{
		Quantity: aws.Int64(int64(qty)),
		Items:    items,
	}
}
func expandETPermList(permissions *schema.Set) []*elastictranscoder.Permission {
	var perms []*elastictranscoder.Permission

	for _, p := range permissions.List() {
		perm := &elastictranscoder.Permission{
			Access:      getStringPtrList(p.(map[string]interface{}), "access"),
			Grantee:     getStringPtr(p, "grantee"),
			GranteeType: getStringPtr(p, "grantee_type"),
		}
		perms = append(perms, perm)
	}
	return perms
}
func extractOptionSettings(s *schema.Set) []*elasticbeanstalk.ConfigurationOptionSetting {
	settings := []*elasticbeanstalk.ConfigurationOptionSetting{}

	if s != nil {
		for _, setting := range s.List() {
			settings = append(settings, &elasticbeanstalk.ConfigurationOptionSetting{
				Namespace:  aws.String(setting.(map[string]interface{})["namespace"].(string)),
				OptionName: aws.String(setting.(map[string]interface{})["name"].(string)),
				Value:      aws.String(setting.(map[string]interface{})["value"].(string)),
			})
		}
	}

	return settings
}
예제 #23
0
// Build a slice of AMI filter options from the filters provided.
func buildAmiFilters(set *schema.Set) []*ec2.Filter {
	var filters []*ec2.Filter
	for _, v := range set.List() {
		m := v.(map[string]interface{})
		var filterValues []*string
		for _, e := range m["values"].([]interface{}) {
			filterValues = append(filterValues, aws.String(e.(string)))
		}
		filters = append(filters, &ec2.Filter{
			Name:   aws.String(m["name"].(string)),
			Values: filterValues,
		})
	}
	return filters
}
func TestCloudFrontStructure_flattenCacheBehavior(t *testing.T) {
	in := cacheBehaviorConf1()
	cb := expandCacheBehavior(in)
	out := flattenCacheBehavior(cb)
	var diff *schema.Set
	if out["compress"] != true {
		t.Fatalf("Expected out[compress] to be true, got %v", out["compress"])
	}
	if out["viewer_protocol_policy"] != "allow-all" {
		t.Fatalf("Expected out[viewer_protocol_policy] to be allow-all, got %v", out["viewer_protocol_policy"])
	}
	if out["target_origin_id"] != "myS3Origin" {
		t.Fatalf("Expected out[target_origin_id] to be myS3Origin, got %v", out["target_origin_id"])
	}
	diff = out["forwarded_values"].(*schema.Set).Difference(in["forwarded_values"].(*schema.Set))
	if len(diff.List()) > 0 {
		t.Fatalf("Expected out[forwarded_values] to be %v, got %v, diff: %v", out["forwarded_values"], in["forwarded_values"], diff)
	}
	if out["min_ttl"] != int(86400) {
		t.Fatalf("Expected out[min_ttl] to be 86400 (int), got %v", out["forwarded_values"])
	}
	if reflect.DeepEqual(out["trusted_signers"], in["trusted_signers"]) != true {
		t.Fatalf("Expected out[trusted_signers] to be %v, got %v", in["trusted_signers"], out["trusted_signers"])
	}
	if out["max_ttl"] != int(365000000) {
		t.Fatalf("Expected out[max_ttl] to be 365000000 (int), got %v", out["max_ttl"])
	}
	if out["smooth_streaming"] != false {
		t.Fatalf("Expected out[smooth_streaming] to be false, got %v", out["smooth_streaming"])
	}
	if out["default_ttl"] != int(86400) {
		t.Fatalf("Expected out[default_ttl] to be 86400 (int), got %v", out["default_ttl"])
	}
	if reflect.DeepEqual(out["allowed_methods"], in["allowed_methods"]) != true {
		t.Fatalf("Expected out[allowed_methods] to be %v, got %v", in["allowed_methods"], out["allowed_methods"])
	}
	if reflect.DeepEqual(out["cached_methods"], in["cached_methods"]) != true {
		t.Fatalf("Expected out[cached_methods] to be %v, got %v", in["cached_methods"], out["cached_methods"])
	}
	if out["path_pattern"] != "/path1" {
		t.Fatalf("Expected out[path_pattern] to be /path1, got %v", out["path_pattern"])
	}
}
func extractOptionSettings(s *schema.Set) []*elasticbeanstalk.ConfigurationOptionSetting {
	settings := []*elasticbeanstalk.ConfigurationOptionSetting{}

	if s != nil {
		for _, setting := range s.List() {
			optionSetting := elasticbeanstalk.ConfigurationOptionSetting{
				Namespace:  aws.String(setting.(map[string]interface{})["namespace"].(string)),
				OptionName: aws.String(setting.(map[string]interface{})["name"].(string)),
				Value:      aws.String(setting.(map[string]interface{})["value"].(string)),
			}
			if *optionSetting.Namespace == "aws:autoscaling:scheduledaction" {
				if v, ok := setting.(map[string]interface{})["resource"].(string); ok && v != "" {
					optionSetting.ResourceName = aws.String(v)
				}
			}
			settings = append(settings, &optionSetting)
		}
	}

	return settings
}
func ipamConfigSetToIpamConfigs(ipamConfigSet *schema.Set) []dc.IPAMConfig {
	ipamConfigs := make([]dc.IPAMConfig, ipamConfigSet.Len())

	for i, ipamConfigInt := range ipamConfigSet.List() {
		ipamConfigRaw := ipamConfigInt.(map[string]interface{})

		ipamConfig := dc.IPAMConfig{}
		ipamConfig.Subnet = ipamConfigRaw["subnet"].(string)
		ipamConfig.IPRange = ipamConfigRaw["ip_range"].(string)
		ipamConfig.Gateway = ipamConfigRaw["gateway"].(string)

		auxAddressRaw := ipamConfigRaw["aux_address"].(map[string]interface{})
		ipamConfig.AuxAddress = make(map[string]string, len(auxAddressRaw))
		for k, v := range auxAddressRaw {
			ipamConfig.AuxAddress[k] = v.(string)
		}

		ipamConfigs[i] = ipamConfig
	}

	return ipamConfigs
}
func deleteEgressFirewallRules(
	d *schema.ResourceData,
	meta interface{},
	rules *schema.Set,
	ors *schema.Set) error {
	var errs *multierror.Error

	var wg sync.WaitGroup
	wg.Add(ors.Len())

	sem := make(chan struct{}, 10)
	for _, rule := range ors.List() {
		// Put a sleep here to avoid DoS'ing the API
		time.Sleep(500 * time.Millisecond)

		go func(rule map[string]interface{}) {
			defer wg.Done()
			sem <- struct{}{}

			// Delete a single rule
			err := deleteEgressFirewallRule(d, meta, rule)

			// If we have at least one UUID, we need to save the rule
			if len(rule["uuids"].(map[string]interface{})) > 0 {
				rules.Add(rule)
			}

			if err != nil {
				errs = multierror.Append(errs, err)
			}

			<-sem
		}(rule.(map[string]interface{}))
	}

	wg.Wait()

	return errs.ErrorOrNil()
}
func getListOfUsersByIdOrUsername(roleUsers []configuration.User, usersWithIdOrName *schema.Set) *schema.Set {
	mappedList := []interface{}{}
	for _, user := range roleUsers {
		found := false
		for _, idOrUsername := range usersWithIdOrName.List() {
			if isID(idOrUsername.(string)) {
				if strings.EqualFold(user.Id, idOrUsername.(string)) {
					found = true
					mappedList = append(mappedList, user.Id)
					break
				}
			} else if strings.EqualFold(user.Username, idOrUsername.(string)) {
				found = true
				mappedList = append(mappedList, user.Username)
				break
			}
		}
		if !found {
			mappedList = append(mappedList, user.Username)
		}
	}
	return schema.NewSet(schema.HashSchema(&schema.Schema{Type: schema.TypeString}), mappedList)
}
// matchRules receives the group id, type of rules, and the local / remote maps
// of rules. We iterate through the local set of rules trying to find a matching
// remote rule, which may be structured differently because of how AWS
// aggregates the rules under the to, from, and type.
//
//
// Matching rules are written to state, with their elements removed from the
// remote set
//
// If no match is found, we'll write the remote rule to state and let the graph
// sort things out
func matchRules(rType string, local []interface{}, remote []map[string]interface{}) []map[string]interface{} {
	// For each local ip or security_group, we need to match against the remote
	// ruleSet until all ips or security_groups are found

	// saves represents the rules that have been identified to be saved to state,
	// in the appropriate d.Set("{ingress,egress}") call.
	var saves []map[string]interface{}
	for _, raw := range local {
		l := raw.(map[string]interface{})

		var selfVal bool
		if v, ok := l["self"]; ok {
			selfVal = v.(bool)
		}

		// matching against self is required to detect rules that only include self
		// as the rule. resourceAwsSecurityGroupIPPermGather parses the group out
		// and replaces it with self if it's ID is found
		localHash := idHash(rType, l["protocol"].(string), int64(l["to_port"].(int)), int64(l["from_port"].(int)), selfVal)

		// loop remote rules, looking for a matching hash
		for _, r := range remote {
			var remoteSelfVal bool
			if v, ok := r["self"]; ok {
				remoteSelfVal = v.(bool)
			}

			// hash this remote rule and compare it for a match consideration with the
			// local rule we're examining
			rHash := idHash(rType, r["protocol"].(string), r["to_port"].(int64), r["from_port"].(int64), remoteSelfVal)
			if rHash == localHash {
				var numExpectedCidrs, numExpectedSGs, numRemoteCidrs, numRemoteSGs int
				var matchingCidrs []string
				var matchingSGs []string

				// grab the local/remote cidr and sg groups, capturing the expected and
				// actual counts
				lcRaw, ok := l["cidr_blocks"]
				if ok {
					numExpectedCidrs = len(l["cidr_blocks"].([]interface{}))
				}
				lsRaw, ok := l["security_groups"]
				if ok {
					numExpectedSGs = len(l["security_groups"].(*schema.Set).List())
				}

				rcRaw, ok := r["cidr_blocks"]
				if ok {
					numRemoteCidrs = len(r["cidr_blocks"].([]string))
				}

				rsRaw, ok := r["security_groups"]
				if ok {
					numRemoteSGs = len(r["security_groups"].(*schema.Set).List())
				}

				// check some early failures
				if numExpectedCidrs > numRemoteCidrs {
					log.Printf("[DEBUG] Local rule has more CIDR blocks, continuing (%d/%d)", numExpectedCidrs, numRemoteCidrs)
					continue
				}
				if numExpectedSGs > numRemoteSGs {
					log.Printf("[DEBUG] Local rule has more Security Groups, continuing (%d/%d)", numExpectedSGs, numRemoteSGs)
					continue
				}

				// match CIDRs by converting both to sets, and using Set methods
				var localCidrs []interface{}
				if lcRaw != nil {
					localCidrs = lcRaw.([]interface{})
				}
				localCidrSet := schema.NewSet(schema.HashString, localCidrs)

				// remote cidrs are presented as a slice of strings, so we need to
				// reformat them into a slice of interfaces to be used in creating the
				// remote cidr set
				var remoteCidrs []string
				if rcRaw != nil {
					remoteCidrs = rcRaw.([]string)
				}
				// convert remote cidrs to a set, for easy comparisions
				var list []interface{}
				for _, s := range remoteCidrs {
					list = append(list, s)
				}
				remoteCidrSet := schema.NewSet(schema.HashString, list)

				// Build up a list of local cidrs that are found in the remote set
				for _, s := range localCidrSet.List() {
					if remoteCidrSet.Contains(s) {
						matchingCidrs = append(matchingCidrs, s.(string))
					}
				}

				// match SGs. Both local and remote are already sets
				var localSGSet *schema.Set
				if lsRaw == nil {
					localSGSet = schema.NewSet(schema.HashString, nil)
				} else {
					localSGSet = lsRaw.(*schema.Set)
				}

				var remoteSGSet *schema.Set
				if rsRaw == nil {
					remoteSGSet = schema.NewSet(schema.HashString, nil)
				} else {
					remoteSGSet = rsRaw.(*schema.Set)
				}

				// Build up a list of local security groups that are found in the remote set
				for _, s := range localSGSet.List() {
					if remoteSGSet.Contains(s) {
						matchingSGs = append(matchingSGs, s.(string))
					}
				}

				// compare equalities for matches.
				// If we found the number of cidrs and number of sgs, we declare a
				// match, and then remove those elements from the remote rule, so that
				// this remote rule can still be considered by other local rules
				if numExpectedCidrs == len(matchingCidrs) {
					if numExpectedSGs == len(matchingSGs) {
						// confirm that self references match
						var lSelf bool
						var rSelf bool
						if _, ok := l["self"]; ok {
							lSelf = l["self"].(bool)
						}
						if _, ok := r["self"]; ok {
							rSelf = r["self"].(bool)
						}
						if rSelf == lSelf {
							delete(r, "self")
							// pop local cidrs from remote
							diffCidr := remoteCidrSet.Difference(localCidrSet)
							var newCidr []string
							for _, cRaw := range diffCidr.List() {
								newCidr = append(newCidr, cRaw.(string))
							}

							// reassigning
							if len(newCidr) > 0 {
								r["cidr_blocks"] = newCidr
							} else {
								delete(r, "cidr_blocks")
							}

							// pop local sgs from remote
							diffSGs := remoteSGSet.Difference(localSGSet)
							if len(diffSGs.List()) > 0 {
								r["security_groups"] = diffSGs
							} else {
								delete(r, "security_groups")
							}

							saves = append(saves, l)
						}
					}
				}
			}
		}
	}

	// Here we catch any remote rules that have not been stripped of all self,
	// cidrs, and security groups. We'll add remote rules here that have not been
	// matched locally, and let the graph sort things out. This will happen when
	// rules are added externally to Terraform
	for _, r := range remote {
		var lenCidr, lenSGs int
		if rCidrs, ok := r["cidr_blocks"]; ok {
			lenCidr = len(rCidrs.([]string))
		}

		if rawSGs, ok := r["security_groups"]; ok {
			lenSGs = len(rawSGs.(*schema.Set).List())
		}

		if _, ok := r["self"]; ok {
			if r["self"].(bool) == true {
				lenSGs++
			}
		}

		if lenSGs+lenCidr > 0 {
			log.Printf("[DEBUG] Found a remote Rule that wasn't empty: (%#v)", r)
			saves = append(saves, r)
		}
	}

	return saves
}
예제 #30
0
// Takes the result of schema.Set of strings and returns a []*string
func expandStringSet(configured *schema.Set) []*string {
	return expandStringList(configured.List())
}