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()) }
// 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 }
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 }
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 }
// 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 }
// 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 }
// Takes the result of schema.Set of strings and returns a []*string func expandStringSet(configured *schema.Set) []*string { return expandStringList(configured.List()) }