func (srv *Server) describeSecurityGroups(w http.ResponseWriter, req *http.Request, reqId string) interface{} { // BUG similar bug to describeInstances, but for GroupName and GroupId srv.mu.Lock() defer srv.mu.Unlock() var groups []*securityGroup for name, vals := range req.Form { var g ec2.SecurityGroup switch { case strings.HasPrefix(name, "GroupName."): g.Name = vals[0] case strings.HasPrefix(name, "GroupId."): g.Id = vals[0] default: continue } sg := srv.group(g) if sg == nil { fatalf(400, "InvalidGroup.NotFound", "no such group %v", g) } groups = append(groups, sg) } if len(groups) == 0 { for _, g := range srv.groups { groups = append(groups, g) } } f := newFilter(req.Form) var resp ec2.SecurityGroupsResp resp.RequestId = reqId for _, group := range groups { ok, err := f.ok(group) if ok { resp.Groups = append(resp.Groups, ec2.SecurityGroupInfo{ OwnerId: ownerId, SecurityGroup: group.ec2SecurityGroup(), Description: group.description, IPPerms: group.ec2Perms(), }) } else if err != nil { fatalf(400, "InvalidParameterValue", "describe security groups: %v", err) } } return &resp }
func resource_aws_instance_create( s *terraform.ResourceState, d *terraform.ResourceDiff, meta interface{}) (*terraform.ResourceState, error) { p := meta.(*ResourceProvider) ec2conn := p.ec2conn // Merge the diff into the state so that we have all the attributes // properly. rs := s.MergeDiff(d) delete(rs.Attributes, "source_dest_check") // Figure out user data userData := "" if attr, ok := d.Attributes["user_data"]; ok { userData = attr.NewExtra.(string) } associatePublicIPAddress := false if rs.Attributes["associate_public_ip_address"] == "true" { associatePublicIPAddress = true } // Build the creation struct runOpts := &ec2.RunInstances{ ImageId: rs.Attributes["ami"], InstanceType: rs.Attributes["instance_type"], KeyName: rs.Attributes["key_name"], SubnetId: rs.Attributes["subnet_id"], AssociatePublicIpAddress: associatePublicIPAddress, UserData: []byte(userData), } if raw := flatmap.Expand(rs.Attributes, "security_groups"); raw != nil { if sgs, ok := raw.([]interface{}); ok { for _, sg := range sgs { str, ok := sg.(string) if !ok { continue } var g ec2.SecurityGroup if runOpts.SubnetId != "" { g.Id = str } else { g.Name = str } runOpts.SecurityGroups = append(runOpts.SecurityGroups, g) } } } // Create the instance log.Printf("[DEBUG] Run configuration: %#v", runOpts) runResp, err := ec2conn.RunInstances(runOpts) if err != nil { return nil, fmt.Errorf("Error launching source instance: %s", err) } instance := &runResp.Instances[0] log.Printf("[INFO] Instance ID: %s", instance.InstanceId) // Store the resulting ID so we can look this up later rs.ID = instance.InstanceId // Wait for the instance to become running so we can get some attributes // that aren't available until later. log.Printf( "[DEBUG] Waiting for instance (%s) to become running", instance.InstanceId) stateConf := &resource.StateChangeConf{ Pending: []string{"pending"}, Target: "running", Refresh: InstanceStateRefreshFunc(ec2conn, instance.InstanceId), Timeout: 10 * time.Minute, Delay: 10 * time.Second, MinTimeout: 3 * time.Second, } instanceRaw, err := stateConf.WaitForState() if err != nil { return rs, fmt.Errorf( "Error waiting for instance (%s) to become ready: %s", instance.InstanceId, err) } instance = instanceRaw.(*ec2.Instance) // Initialize the connection info rs.ConnInfo["type"] = "ssh" rs.ConnInfo["host"] = instance.PublicIpAddress // Set our attributes rs, err = resource_aws_instance_update_state(rs, instance) if err != nil { return rs, err } // Update if we need to return resource_aws_instance_update(rs, d, meta) }
// parsePerms returns a slice of permKey values extracted // from the permission fields in req. func (srv *Server) parsePerms(req *http.Request) []permKey { // perms maps an index found in the form to its associated // IPPerm. For instance, the form value with key // "IpPermissions.3.FromPort" will be stored in perms[3].FromPort perms := make(map[int]ec2.IPPerm) type subgroupKey struct { id1, id2 int } // Each IPPerm can have many source security groups. The form key // for a source security group contains two indices: the index // of the IPPerm and the sub-index of the security group. The // sourceGroups map maps from a subgroupKey containing these // two indices to the associated security group. For instance, // the form value with key "IPPermissions.3.Groups.2.GroupName" // will be stored in sourceGroups[subgroupKey{3, 2}].Name. sourceGroups := make(map[subgroupKey]ec2.UserSecurityGroup) // For each value in the form we store its associated information in the // above maps. The maps are necessary because the form keys may // arrive in any order, and the indices are not // necessarily sequential or even small. for name, vals := range req.Form { val := vals[0] var id1 int var rest string if x, _ := fmt.Sscanf(name, "IpPermissions.%d.%s", &id1, &rest); x != 2 { continue } ec2p := perms[id1] switch { case rest == "FromPort": ec2p.FromPort = atoi(val) case rest == "ToPort": ec2p.ToPort = atoi(val) case rest == "IpProtocol": switch val { case "tcp", "udp", "icmp": ec2p.Protocol = val default: // check it's a well formed number atoi(val) ec2p.Protocol = val } case strings.HasPrefix(rest, "Groups."): k := subgroupKey{id1: id1} if x, _ := fmt.Sscanf(rest[len("Groups."):], "%d.%s", &k.id2, &rest); x != 2 { continue } g := sourceGroups[k] switch rest { case "UserId": // BUG if the user id is blank, this does not conform to the // way that EC2 handles it - a specified but blank owner id // can cause RevokeSecurityGroupIngress to fail with // "group not found" even if the security group id has been // correctly specified. // By failing here, we ensure that we fail early in this case. if !ownerIdPat.MatchString(val) { fatalf(400, "InvalidUserID.Malformed", "Invalid user ID: %q", val) } g.OwnerId = val case "GroupName": g.Name = val case "GroupId": if !secGroupPat.MatchString(val) { fatalf(400, "InvalidGroupId.Malformed", "Invalid group ID: %q", val) } g.Id = val default: fatalf(400, "UnknownParameter", "unknown parameter %q", name) } sourceGroups[k] = g case strings.HasPrefix(rest, "IpRanges."): var id2 int if x, _ := fmt.Sscanf(rest[len("IpRanges."):], "%d.%s", &id2, &rest); x != 2 { continue } switch rest { case "CidrIp": if !ipPat.MatchString(val) { fatalf(400, "InvalidPermission.Malformed", "Invalid IP range: %q", val) } ec2p.SourceIPs = append(ec2p.SourceIPs, val) default: fatalf(400, "UnknownParameter", "unknown parameter %q", name) } default: fatalf(400, "UnknownParameter", "unknown parameter %q", name) } perms[id1] = ec2p } // Associate each set of source groups with its IPPerm. for k, g := range sourceGroups { p := perms[k.id1] p.SourceGroups = append(p.SourceGroups, g) perms[k.id1] = p } // Now that we have built up the IPPerms we need, we check for // parameter errors and build up a permKey for each permission, // looking up security groups from srv as we do so. var result []permKey for _, p := range perms { if p.FromPort > p.ToPort { fatalf(400, "InvalidParameterValue", "invalid port range") } k := permKey{ protocol: p.Protocol, fromPort: p.FromPort, toPort: p.ToPort, } for _, g := range p.SourceGroups { if g.OwnerId != "" && g.OwnerId != ownerId { fatalf(400, "InvalidGroup.NotFound", "group %q not found", g.Name) } var ec2g ec2.SecurityGroup switch { case g.Id != "": ec2g.Id = g.Id case g.Name != "": ec2g.Name = g.Name } k.group = srv.group(ec2g) if k.group == nil { fatalf(400, "InvalidGroup.NotFound", "group %v not found", g) } result = append(result, k) } k.group = nil for _, ip := range p.SourceIPs { k.ipAddr = ip result = append(result, k) } } return result }
func resourceAwsInstanceCreate(d *schema.ResourceData, meta interface{}) error { p := meta.(*ResourceProvider) ec2conn := p.ec2conn // Figure out user data userData := "" if v := d.Get("user_data"); v != nil { userData = v.(string) } associatePublicIPAddress := false if v := d.Get("associate_public_ip_addresss"); v != nil { associatePublicIPAddress = v.(bool) } // Build the creation struct runOpts := &ec2.RunInstances{ ImageId: d.Get("ami").(string), AvailZone: d.Get("availability_zone").(string), InstanceType: d.Get("instance_type").(string), KeyName: d.Get("key_name").(string), SubnetId: d.Get("subnet_id").(string), PrivateIPAddress: d.Get("private_ip").(string), AssociatePublicIpAddress: associatePublicIPAddress, UserData: []byte(userData), } if v := d.Get("security_groups"); v != nil { for _, v := range v.(*schema.Set).List() { str := v.(string) var g ec2.SecurityGroup if runOpts.SubnetId != "" { g.Id = str } else { g.Name = str } runOpts.SecurityGroups = append(runOpts.SecurityGroups, g) } } // Create the instance log.Printf("[DEBUG] Run configuration: %#v", runOpts) runResp, err := ec2conn.RunInstances(runOpts) if err != nil { return fmt.Errorf("Error launching source instance: %s", err) } instance := &runResp.Instances[0] log.Printf("[INFO] Instance ID: %s", instance.InstanceId) // Store the resulting ID so we can look this up later d.SetId(instance.InstanceId) // Wait for the instance to become running so we can get some attributes // that aren't available until later. log.Printf( "[DEBUG] Waiting for instance (%s) to become running", instance.InstanceId) stateConf := &resource.StateChangeConf{ Pending: []string{"pending"}, Target: "running", Refresh: InstanceStateRefreshFunc(ec2conn, instance.InstanceId), Timeout: 10 * time.Minute, Delay: 10 * time.Second, MinTimeout: 3 * time.Second, } instanceRaw, err := stateConf.WaitForState() if err != nil { return fmt.Errorf( "Error waiting for instance (%s) to become ready: %s", instance.InstanceId, err) } instance = instanceRaw.(*ec2.Instance) // Initialize the connection info d.SetConnInfo(map[string]string{ "type": "ssh", "host": instance.PublicIpAddress, }) // Set our attributes if err := resourceAwsInstanceRead(d, meta); err != nil { return err } // Update if we need to return resourceAwsInstanceUpdate(d, meta) }
func resourceAwsInstanceCreate(d *schema.ResourceData, meta interface{}) error { ec2conn := meta.(*AWSClient).ec2conn // Figure out user data userData := "" if v := d.Get("user_data"); v != nil { userData = v.(string) } associatePublicIPAddress := false if v := d.Get("associate_public_ip_address"); v != nil { associatePublicIPAddress = v.(bool) } // Build the creation struct runOpts := &ec2.RunInstances{ ImageId: d.Get("ami").(string), AvailZone: d.Get("availability_zone").(string), InstanceType: d.Get("instance_type").(string), KeyName: d.Get("key_name").(string), SubnetId: d.Get("subnet_id").(string), PrivateIPAddress: d.Get("private_ip").(string), AssociatePublicIpAddress: associatePublicIPAddress, UserData: []byte(userData), EbsOptimized: d.Get("ebs_optimized").(bool), IamInstanceProfile: d.Get("iam_instance_profile").(string), Tenancy: d.Get("tenancy").(string), } if v := d.Get("security_groups"); v != nil { for _, v := range v.(*schema.Set).List() { str := v.(string) var g ec2.SecurityGroup if runOpts.SubnetId != "" { g.Id = str } else { g.Name = str } runOpts.SecurityGroups = append(runOpts.SecurityGroups, g) } } if v := d.Get("block_device"); v != nil { vs := v.(*schema.Set).List() if len(vs) > 0 { runOpts.BlockDevices = make([]ec2.BlockDeviceMapping, len(vs)) for i, v := range vs { bd := v.(map[string]interface{}) runOpts.BlockDevices[i].DeviceName = bd["device_name"].(string) runOpts.BlockDevices[i].VirtualName = bd["virtual_name"].(string) runOpts.BlockDevices[i].SnapshotId = bd["snapshot_id"].(string) runOpts.BlockDevices[i].VolumeType = bd["volume_type"].(string) runOpts.BlockDevices[i].VolumeSize = int64(bd["volume_size"].(int)) runOpts.BlockDevices[i].DeleteOnTermination = bd["delete_on_termination"].(bool) runOpts.BlockDevices[i].Encrypted = bd["encrypted"].(bool) } } } // Create the instance log.Printf("[DEBUG] Run configuration: %#v", runOpts) runResp, err := ec2conn.RunInstances(runOpts) if err != nil { return fmt.Errorf("Error launching source instance: %s", err) } instance := &runResp.Instances[0] log.Printf("[INFO] Instance ID: %s", instance.InstanceId) // Store the resulting ID so we can look this up later d.SetId(instance.InstanceId) // Wait for the instance to become running so we can get some attributes // that aren't available until later. log.Printf( "[DEBUG] Waiting for instance (%s) to become running", instance.InstanceId) stateConf := &resource.StateChangeConf{ Pending: []string{"pending"}, Target: "running", Refresh: InstanceStateRefreshFunc(ec2conn, instance.InstanceId), Timeout: 10 * time.Minute, Delay: 10 * time.Second, MinTimeout: 3 * time.Second, } instanceRaw, err := stateConf.WaitForState() if err != nil { return fmt.Errorf( "Error waiting for instance (%s) to become ready: %s", instance.InstanceId, err) } instance = instanceRaw.(*ec2.Instance) // Initialize the connection info d.SetConnInfo(map[string]string{ "type": "ssh", "host": instance.PublicIpAddress, }) // Set our attributes if err := resourceAwsInstanceRead(d, meta); err != nil { return err } // Update if we need to return resourceAwsInstanceUpdate(d, meta) }