// handleSingleMessage processes a single refresh credentials message. func (refreshHandler *refreshCredentialsHandler) handleSingleMessage(message *ecsacs.IAMRoleCredentialsMessage) error { // Validate fields in the message err := validateIAMRoleCredentialsMessage(message) if err != nil { seelog.Errorf("Error validating credentials message: %v", err) return err } taskArn := aws.StringValue(message.TaskArn) messageId := aws.StringValue(message.MessageId) task, ok := refreshHandler.taskEngine.GetTaskByArn(taskArn) if !ok { seelog.Errorf("Task not found in the engine for the arn in credentials message, arn: %s, messageId: %s", taskArn, messageId) return fmt.Errorf("Task not found in the engine for the arn in credentials message, arn: %s", taskArn) } taskCredentials := credentials.TaskIAMRoleCredentials{ ARN: taskArn, IAMRoleCredentials: credentials.IAMRoleCredentialsFromACS(message.RoleCredentials), } err = refreshHandler.credentialsManager.SetTaskCredentials(taskCredentials) if err != nil { seelog.Errorf("Error updating credentials, err: %v messageId: %s", err, messageId) return fmt.Errorf("Error updating credentials %v", err) } task.SetCredentialsId(aws.StringValue(message.RoleCredentials.CredentialsId)) go func() { response := &ecsacs.IAMRoleCredentialsAckRequest{ Expiration: message.RoleCredentials.Expiration, MessageId: message.MessageId, CredentialsId: message.RoleCredentials.CredentialsId, } refreshHandler.ackRequest <- response }() return nil }
// Down stops any running containers(tasks) by calling Stop() and deletes an active ECS Service // NoOp if the service is inactive func (s *Service) Down() error { // describe the service ecsService, err := s.describeService() if err != nil { return err } ecsServiceName := aws.StringValue(ecsService.ServiceName) // if already deleted, NoOp if aws.StringValue(ecsService.Status) != ecsActiveResourceCode { log.WithFields(log.Fields{ "serviceName": ecsServiceName, }).Info("ECS Service is already deleted") return nil } // stop any running tasks if aws.Int64Value(ecsService.DesiredCount) != 0 { if err = s.Stop(); err != nil { return err } } // deleteService if err = s.Context().ECSClient.DeleteService(ecsServiceName); err != nil { return err } return waitForServiceTasks(s, ecsServiceName) }
// Release releases all address for the given region/client // // TODO(rjeczalik): add logger func (a *Addresses) Release(client *amazon.Client) { if len(a.m) == 0 { return } addresses := a.m[client] fmt.Printf("Releasing %d addresses for region %s\n", len(addresses), client.Region) for _, addr := range addresses { ip := aws.StringValue(addr.PublicIp) assocID := aws.StringValue(addr.AssociationId) if assocID != "" { // EIP is in-use, disassociate it first. err := client.DisassociateAddress(assocID) if err != nil { // Even when it fails, will try to release the EIP. fmt.Printf("[%s] disassociate %s EIP error: %s\n", client.Region, ip, err) } } allocID := aws.StringValue(addr.AllocationId) err := client.ReleaseAddress(allocID) if err != nil { fmt.Printf("[%s] release %s EIP error: %s\n", client.Region, ip, err) } } fmt.Printf("Releasing is done for region %s\n", client.Region) }
func (a *AWSVolumes) discoverTags() error { instance, err := a.describeInstance() if err != nil { return err } tagMap := make(map[string]string) for _, tag := range instance.Tags { tagMap[aws.StringValue(tag.Key)] = aws.StringValue(tag.Value) } clusterID := tagMap[TagNameKubernetesCluster] if clusterID == "" { return fmt.Errorf("Cluster tag %q not found on this instance (%q)", TagNameKubernetesCluster, a.instanceId) } a.clusterTag = clusterID a.internalIP = net.ParseIP(aws.StringValue(instance.PrivateIpAddress)) if a.internalIP == nil { return fmt.Errorf("Internal IP not found on this instance (%q)", a.instanceId) } return nil }
func (s3 *s3driver) CheckDataAndGetSize(dpconn, itemlocation, fileName string) (exist bool, size int64, err error) { bucket := getAwsInfoFromDpconn(dpconn) destFullPathFileName := bucket + "/" + itemlocation + "/" + fileName log.Info(destFullPathFileName) AWS_REGION = Env("AWS_REGION", false) svc := s3aws.New(session.New(&aws.Config{Region: aws.String(AWS_REGION)})) result, err := svc.ListObjects(&s3aws.ListObjectsInput{Bucket: aws.String(bucket), Prefix: aws.String(itemlocation + "/" + fileName)}) if err != nil { log.Error("Failed to list objects", err) return exist, size, err } exist = false for _, v := range result.Contents { log.Infof("Tag:%s, key:%s, size:%v\n", aws.StringValue(v.ETag), aws.StringValue(v.Key), aws.Int64Value(v.Size)) if aws.StringValue(v.Key) == fileName { size = aws.Int64Value(v.Size) exist = true } } return }
func (c *DeleteCluster) ListResources() (map[string]*ResourceTracker, error) { cloud := c.Cloud.(*awsup.AWSCloud) resources := make(map[string]*ResourceTracker) listFunctions := []listFn{ ListSubnets, ListRouteTables, ListSecurityGroups, ListInstances, ListDhcpOptions, ListInternetGateways, ListVPCs, ListVolumes, // ELBs ListELBs, // ASG ListAutoScalingGroups, ListAutoScalingLaunchConfigurations, } for _, fn := range listFunctions { trackers, err := fn(cloud, c.ClusterName) if err != nil { return nil, err } for _, t := range trackers { resources[t.Type+":"+t.ID] = t } } { // Gateways weren't tagged in kube-up // If we are deleting the VPC, we should delete the attached gateway // (no real reason not to; easy to recreate; no real state etc) gateways, err := DescribeInternetGatewaysIgnoreTags(cloud) if err != nil { return nil, err } for _, igw := range gateways { for _, attachment := range igw.Attachments { vpcID := aws.StringValue(attachment.VpcId) igwID := aws.StringValue(igw.InternetGatewayId) if vpcID == "" || igwID == "" { continue } if resources["vpc:"+vpcID] != nil && resources["internet-gateway:"+igwID] == nil { resources["internet-gateway:"+igwID] = &ResourceTracker{ Name: FindName(igw.Tags), ID: igwID, Type: "internet-gateway", deleter: DeleteInternetGateway, } } } } } for k, t := range resources { if t.done { delete(resources, k) } } return resources, nil }
func ListVPCs(cloud fi.Cloud, clusterName string) ([]*ResourceTracker, error) { c := cloud.(*awsup.AWSCloud) glog.V(2).Infof("Listing EC2 VPC") request := &ec2.DescribeVpcsInput{ Filters: buildEC2Filters(cloud), } response, err := c.EC2.DescribeVpcs(request) if err != nil { return nil, fmt.Errorf("error listing VPCs: %v", err) } var trackers []*ResourceTracker for _, v := range response.Vpcs { tracker := &ResourceTracker{ Name: FindName(v.Tags), ID: aws.StringValue(v.VpcId), Type: "vpc", deleter: DeleteVPC, } var blocks []string blocks = append(blocks, "dhcp-options:"+aws.StringValue(v.DhcpOptionsId)) tracker.blocks = blocks trackers = append(trackers, tracker) } return trackers, nil }
// constructTaskDefinitionCacheHash computes md5sum of the region, awsAccountId and the requested task definition data // BUG(juanrhenals) The requested Task Definition data (taskDefinitionRequest) is not created in a deterministic fashion because there are maps within // the request ecs.RegisterTaskDefinitionInput structure, and map iteration in Go is not deterministic. We need to fix this. func (client *ecsClient) constructTaskDefinitionCacheHash(taskDefinition *ecs.TaskDefinition, request *ecs.RegisterTaskDefinitionInput) string { // Get the region from the ecsClient configuration region := aws.StringValue(client.params.Config.Region) awsUserAccountId := utils.GetAwsAccountIdFromArn(aws.StringValue(taskDefinition.TaskDefinitionArn)) tdHashInput := fmt.Sprintf("%s-%s-%s", region, awsUserAccountId, request.GoString()) return fmt.Sprintf("%x", md5.Sum([]byte(tdHashInput))) }
func (s *Session) clientConfigWithErr(serviceName string, cfgs ...*aws.Config) (client.Config, error) { s = s.Copy(cfgs...) var resolved endpoints.ResolvedEndpoint var err error region := aws.StringValue(s.Config.Region) if endpoint := aws.StringValue(s.Config.Endpoint); len(endpoint) != 0 { resolved.URL = endpoints.AddScheme(endpoint, aws.BoolValue(s.Config.DisableSSL)) resolved.SigningRegion = region } else { resolved, err = s.Config.EndpointResolver.EndpointFor( serviceName, region, func(opt *endpoints.Options) { opt.DisableSSL = aws.BoolValue(s.Config.DisableSSL) opt.UseDualStack = aws.BoolValue(s.Config.UseDualStack) }, ) } return client.Config{ Config: s.Config, Handlers: s.Handlers, Endpoint: resolved.URL, SigningRegion: resolved.SigningRegion, SigningName: resolved.SigningName, }, err }
func (fs3 *fakeS3) PutObject(input *s3.PutObjectInput) (*s3.PutObjectOutput, error) { k := aws.StringValue(input.Key) bucket := aws.StringValue(input.Bucket) if strings.HasSuffix(k, "meta.json") { data, err := ioutil.ReadAll(input.Body) if err != nil { return nil, fmt.Errorf("Failed to read body for key %s: %v", k, err) } fs3.m.Lock() fs3.metadata = data fs3.m.Unlock() } else { // gunzip the data and store that gzr, err := gzip.NewReader(input.Body) if err != nil { return nil, fmt.Errorf("Failed to gunzip key %s: %v", k, err) } data, err := ioutil.ReadAll(gzr) if err != nil { return nil, fmt.Errorf("Failed to read body for key %s: %v", k, err) } fs3.m.Lock() fs3.parts[k] = putdata{ data: data, bucket: bucket, enc: aws.StringValue(input.ContentEncoding), ctype: aws.StringValue(input.ContentType), } fs3.m.Unlock() } return nil, nil }
// CreateSnapshot creates a new snapshot from the given volumeId and // description. It waits until it's ready. func (a *Amazon) CreateSnapshot(volumeId, desc string) (*ec2.Snapshot, error) { snapshot, err := a.Client.CreateSnapshot(volumeId, desc) if err != nil { return nil, err } checkSnapshot := func(int) (machinestate.State, error) { s, err := a.Client.SnapshotByID(aws.StringValue(snapshot.SnapshotId)) if IsNotFound(err) { // shouldn't happen but let's check it anyway return machinestate.Pending, nil } if err != nil { return 0, err } if aws.StringValue(s.State) != ec2.SnapshotStateCompleted { return machinestate.Pending, nil } snapshot = s return machinestate.Stopped, nil } ws := waitstate.WaitState{ StateFunc: checkSnapshot, DesiredState: machinestate.Stopped, } if err := ws.Wait(); err != nil { return nil, err } return snapshot, nil }
// handleSingleMessage processes a single payload message. It adds tasks in the message to the task engine // An error is returned if the message was not handled correctly. The error is being used only for testing // today. In the future, it could be used for doing more interesting things. func (payloadHandler *payloadRequestHandler) handleSingleMessage(payload *ecsacs.PayloadMessage) error { if aws.StringValue(payload.MessageId) == "" { seelog.Criticalf("Recieved a payload with no message id, payload: %v", payload) return fmt.Errorf("Received a payload with no message id") } seelog.Debugf("Received payload message, message id: %s", aws.StringValue(payload.MessageId)) credentialsAcks, allTasksHandled := payloadHandler.addPayloadTasks(payload) // save the state of tasks we know about after passing them to the task engine err := payloadHandler.saver.Save() if err != nil { seelog.Errorf("Error saving state for payload message! err: %v, messageId: %s", err, *payload.MessageId) // Don't ack; maybe we can save it in the future. return fmt.Errorf("Error saving state for payload message, with messageId: %s", *payload.MessageId) } if !allTasksHandled { return fmt.Errorf("All tasks not handled") } go func() { // Throw the ack in async; it doesn't really matter all that much and this is blocking handling more tasks. for _, credentialsAck := range credentialsAcks { payloadHandler.refreshHandler.ackMessage(credentialsAck) } payloadHandler.ackRequest <- *payload.MessageId }() return nil }
func (ld *loader) start(infoWriter io.Writer) (done chan error, err error) { var hashKey string for _, s := range ld.tableInfo.KeySchema { if aws.StringValue(s.KeyType) == "HASH" { hashKey = aws.StringValue(s.AttributeName) } } if hashKey == "" { fail("Failed to find hash key for table") } fmt.Fprintf(infoWriter, "Beginning restore: table=%q source=%q writeCapacity=%d parallel=%d totalSize=%s allow-overwrite=%t\n", *ld.tableName, ld.source, *ld.writeCapacity, *ld.parallel, fmtBytes(ld.md.UncompressedBytes), *ld.allowOverwrite) dynLoader := &dyndump.Loader{ Dyn: ld.dyn, TableName: *ld.tableName, MaxParallel: *ld.parallel, MaxItems: int64(*ld.maxItems), WriteCapacity: float64(*ld.writeCapacity), Source: dyndump.NewSimpleDecoder(ld.r), HashKey: hashKey, AllowOverwrite: *ld.allowOverwrite, } ld.loader = dynLoader done = make(chan error, 1) ld.startTime = time.Now() go func() { done <- dynLoader.Run() }() return done, nil }
// taskDefinitionToProcess takes an ECS Task Definition and converts it to a // Process. func taskDefinitionToProcess(td *ecs.TaskDefinition) (*scheduler.Process, error) { // If this task definition has no container definitions, then something // funky is up. if len(td.ContainerDefinitions) == 0 { return nil, errors.New("task definition had no container definitions") } container := td.ContainerDefinitions[0] var command []string for _, s := range container.Command { command = append(command, *s) } env := make(map[string]string) for _, kvp := range container.Environment { if kvp != nil { env[aws.StringValue(kvp.Name)] = aws.StringValue(kvp.Value) } } return &scheduler.Process{ Type: aws.StringValue(container.Name), Command: command, Env: env, CPUShares: uint(*container.Cpu), MemoryLimit: uint(*container.Memory) * MB, Nproc: uint(softLimit(container.Ulimits, "nproc")), }, nil }
func ListSecurityGroups(cloud fi.Cloud, clusterName string) ([]*ResourceTracker, error) { c := cloud.(*awsup.AWSCloud) glog.V(2).Infof("Listing EC2 SecurityGroups") request := &ec2.DescribeSecurityGroupsInput{ Filters: buildEC2Filters(cloud), } response, err := c.EC2.DescribeSecurityGroups(request) if err != nil { return nil, fmt.Errorf("error listing SecurityGroups: %v", err) } var trackers []*ResourceTracker for _, sg := range response.SecurityGroups { tracker := &ResourceTracker{ Name: FindName(sg.Tags), ID: aws.StringValue(sg.GroupId), Type: "security-group", deleter: DeleteSecurityGroup, } var blocks []string blocks = append(blocks, "vpc:"+aws.StringValue(sg.VpcId)) tracker.blocks = blocks trackers = append(trackers, tracker) } return trackers, nil }
func (c *Cluster) Info() (*ClusterInfo, error) { resources := make([]cloudformation.StackResourceSummary, 0) req := cloudformation.ListStackResourcesInput{ StackName: c.clusterName, } for { resp, err := c.svc.ListStackResources(&req) if err != nil { return nil, err } for _, s := range resp.StackResourceSummaries { resources = append(resources, *s) } req.NextToken = resp.NextToken if aws.StringValue(req.NextToken) == "" { break } } var info ClusterInfo for _, r := range resources { switch aws.StringValue(r.LogicalResourceId) { case "EIPController": if r.PhysicalResourceId != nil { info.ControllerIP = *r.PhysicalResourceId } else { return nil, fmt.Errorf("unable to get public IP of controller instance") } } } return &info, nil }
func ListSubnets(cloud fi.Cloud, clusterName string) ([]*ResourceTracker, error) { subnets, err := DescribeSubnets(cloud) if err != nil { return nil, fmt.Errorf("error listing subnets: %v", err) } var trackers []*ResourceTracker for _, subnet := range subnets { tracker := &ResourceTracker{ Name: FindName(subnet.Tags), ID: aws.StringValue(subnet.SubnetId), Type: "subnet", deleter: DeleteSubnet, } var blocks []string blocks = append(blocks, "vpc:"+aws.StringValue(subnet.VpcId)) tracker.blocks = blocks trackers = append(trackers, tracker) } return trackers, nil }
func (gs GlacierStorage) UploadFile(filePath string, encrypter *crypter.Encrypter, remoteFileName string) (map[string]string, error) { result := make(map[string]string) fileReader, err := os.Open(filePath) if err != nil { return result, err } defer fileReader.Close() filename := filepath.Base(filePath) if remoteFileName != "" { filename = filepath.Base(remoteFileName) } params := &glacier.UploadArchiveInput{ AccountId: aws.String("-"), VaultName: aws.String(gs.vault_name), ArchiveDescription: aws.String(filename), Body: fileReader} uploadResult, err := gs.getStorageClient().UploadArchive(params) if err != nil { return result, err } err = fileReader.Close() if err != nil { return result, err } result["ArchiveId"] = aws.StringValue(uploadResult.ArchiveId) result["Checksum"] = aws.StringValue(uploadResult.Checksum) result["Location"] = aws.StringValue(uploadResult.Location) return result, nil }
func ListInternetGateways(cloud fi.Cloud, clusterName string) ([]*ResourceTracker, error) { gateways, err := DescribeInternetGateways(cloud) if err != nil { return nil, err } var trackers []*ResourceTracker for _, o := range gateways { tracker := &ResourceTracker{ Name: FindName(o.Tags), ID: aws.StringValue(o.InternetGatewayId), Type: "internet-gateway", deleter: DeleteInternetGateway, } var blocks []string for _, a := range o.Attachments { if aws.StringValue(a.VpcId) != "" { blocks = append(blocks, "vpc:"+aws.StringValue(a.VpcId)) } } tracker.blocks = blocks trackers = append(trackers, tracker) } return trackers, nil }
func (c *AWSCloud) GetELBTags(loadBalancerName string) (map[string]string, error) { tags := map[string]string{} request := &elb.DescribeTagsInput{ LoadBalancerNames: []*string{&loadBalancerName}, } attempt := 0 for { attempt++ response, err := c.ELB.DescribeTags(request) if err != nil { return nil, fmt.Errorf("error listing tags on %v: %v", loadBalancerName, err) } for _, tagset := range response.TagDescriptions { for _, tag := range tagset.Tags { tags[aws.StringValue(tag.Key)] = aws.StringValue(tag.Value) } } return tags, nil } }
func (c CertificateDescriber) Describe(certificateName string) (Certificate, error) { output, err := c.iamClient.GetServerCertificate(&awsiam.GetServerCertificateInput{ ServerCertificateName: aws.String(certificateName), }) if err != nil { if e, ok := err.(awserr.RequestFailure); ok { if e.StatusCode() == http.StatusNotFound && e.Code() == "NoSuchEntity" { return Certificate{}, CertificateNotFound } } return Certificate{}, err } if output.ServerCertificate == nil || output.ServerCertificate.ServerCertificateMetadata == nil { return Certificate{}, CertificateDescriptionFailure } return Certificate{ Name: aws.StringValue(output.ServerCertificate.ServerCertificateMetadata.ServerCertificateName), ARN: aws.StringValue(output.ServerCertificate.ServerCertificateMetadata.Arn), Body: aws.StringValue(output.ServerCertificate.CertificateBody), Chain: aws.StringValue(output.ServerCertificate.CertificateChain), }, nil }
func (p *Route53DNSProvider) Set(fqdn string, recordType string, value string, ttl time.Duration) error { zone, err := p.getZone() if err != nil { return err } // More correct, and makes the simple comparisons later on work correctly if !strings.HasSuffix(fqdn, ".") { fqdn += "." } existing, err := p.findResourceRecord(aws.StringValue(zone.Id), fqdn, recordType) if err != nil { return err } rrs := &route53.ResourceRecordSet{ Name: aws.String(fqdn), Type: aws.String(recordType), TTL: aws.Int64(int64(ttl.Seconds())), ResourceRecords: []*route53.ResourceRecord{ {Value: aws.String(value)}, }, } if existing != nil { if reflect.DeepEqual(rrs, existing) { glog.V(2).Infof("DNS %q %s record already set to %q", fqdn, recordType, value) return nil } else { glog.Infof("ResourceRecordSet change:") glog.Infof("Existing: %v", DebugString(existing)) glog.Infof("Desired: %v", DebugString(rrs)) } } change := &route53.Change{ Action: aws.String("UPSERT"), ResourceRecordSet: rrs, } changeBatch := &route53.ChangeBatch{} changeBatch.Changes = []*route53.Change{change} request := &route53.ChangeResourceRecordSetsInput{} request.HostedZoneId = zone.Id request.ChangeBatch = changeBatch glog.V(2).Infof("Updating DNS record %q", fqdn) glog.V(4).Infof("route53 request: %s", DebugString(request)) response, err := p.client.ChangeResourceRecordSets(request) if err != nil { return fmt.Errorf("error creating ResourceRecordSets: %v", err) } glog.V(2).Infof("Change id is %q", aws.StringValue(response.ChangeInfo.Id)) return nil }
func TestS3ReadMetadata(t *testing.T) { f := &fakeS3GetLister{ get: func(input *s3.GetObjectInput) (*s3.GetObjectOutput, error) { if bucketName := aws.StringValue(input.Bucket); bucketName != "test-bucket" { return nil, fmt.Errorf("incorrect bucket for list %q", bucketName) } if k := aws.StringValue(input.Key); k != "test-prefix-meta.json" { return nil, errors.New("Incorrect key name " + k) } resp := &s3.GetObjectOutput{ Body: ioutil.NopCloser(strings.NewReader(`{"table_name":"a_table","item_count":1234}`)), } return resp, nil }, } r := &S3Reader{ S3: f, Bucket: "test-bucket", PathPrefix: "test-prefix", } md, err := r.Metadata() if err != nil { t.Fatal("Unexpected error", err) } if md.TableName != "a_table" || md.ItemCount != 1234 { t.Error("incorrect metadata", md) } }
// Marshal parses the response from the aws sdk into an awsm Image func (i *Image) Marshal(image *ec2.Image, region string) { var snapshotID, volSize string root := aws.StringValue(image.RootDeviceType) if root == "ebs" { for _, mapping := range image.BlockDeviceMappings { if *mapping.DeviceName == *image.RootDeviceName { snapshotID = aws.StringValue(mapping.Ebs.SnapshotId) volSize = fmt.Sprintf("%d GB", *mapping.Ebs.VolumeSize) } } } i.Name = GetTagValue("Name", image.Tags) i.Class = GetTagValue("Class", image.Tags) i.CreationDate, _ = time.Parse("2006-01-02T15:04:05.000Z", aws.StringValue(image.CreationDate)) // robots i.CreatedHuman = humanize.Time(i.CreationDate) // humans i.ImageID = aws.StringValue(image.ImageId) i.State = aws.StringValue(image.State) i.Root = root i.SnapshotID = snapshotID i.VolumeSize = volSize i.Region = region }
func rootBlockDeviceToSet( bdm []*ec2.BlockDeviceMapping, rootDevName *string, ) *schema.Set { set := &schema.Set{F: hashRootBlockDevice} if rootDevName != nil { for _, val := range bdm { if aws.StringValue(val.DeviceName) == aws.StringValue(rootDevName) { m := make(map[string]interface{}) if val.Ebs.DeleteOnTermination != nil { m["delete_on_termination"] = aws.BoolValue(val.Ebs.DeleteOnTermination) } if val.Ebs.VolumeSize != nil { m["volume_size"] = aws.Int64Value(val.Ebs.VolumeSize) } if val.Ebs.VolumeType != nil { m["volume_type"] = aws.StringValue(val.Ebs.VolumeType) } if val.Ebs.Iops != nil { m["iops"] = aws.Int64Value(val.Ebs.Iops) } set.Add(m) } } } return set }
func (a AWS) GetEC2InstanceTags(instanceID string) map[string]string { describeInstanceInput := &awsec2.DescribeInstancesInput{ DryRun: awslib.Bool(false), Filters: []*awsec2.Filter{ { Name: awslib.String("instance-id"), Values: []*string{ awslib.String(instanceID), }, }, }, InstanceIds: []*string{ awslib.String(instanceID), }, } describeInstancesOutput, err := a.ec2Client.DescribeInstances(describeInstanceInput) Expect(err).NotTo(HaveOccurred()) Expect(describeInstancesOutput.Reservations).To(HaveLen(1)) Expect(describeInstancesOutput.Reservations[0].Instances).To(HaveLen(1)) instance := describeInstancesOutput.Reservations[0].Instances[0] tags := make(map[string]string) for _, tag := range instance.Tags { tags[awslib.StringValue(tag.Key)] = awslib.StringValue(tag.Value) } return tags }
func (i *IAMUser) Describe(userName string) (UserDetails, error) { userDetails := UserDetails{ UserName: userName, } getUserInput := &iam.GetUserInput{ UserName: aws.String(userName), } i.logger.Debug("get-user", lager.Data{"input": getUserInput}) getUserOutput, err := i.iamsvc.GetUser(getUserInput) if err != nil { i.logger.Error("aws-iam-error", err) if awsErr, ok := err.(awserr.Error); ok { return userDetails, errors.New(awsErr.Code() + ": " + awsErr.Message()) } return userDetails, err } i.logger.Debug("get-user", lager.Data{"output": getUserOutput}) userDetails.UserARN = aws.StringValue(getUserOutput.User.Arn) userDetails.UserID = aws.StringValue(getUserOutput.User.UserId) return userDetails, nil }
func ListELBs(cloud fi.Cloud, clusterName string) ([]*ResourceTracker, error) { elbs, elbTags, err := DescribeELBs(cloud) if err != nil { return nil, err } var trackers []*ResourceTracker for _, elb := range elbs { id := aws.StringValue(elb.LoadBalancerName) tracker := &ResourceTracker{ Name: FindELBName(elbTags[id]), ID: id, Type: "load-balancer", deleter: DeleteELB, } var blocks []string for _, sg := range elb.SecurityGroups { blocks = append(blocks, "security-group:"+aws.StringValue(sg)) } for _, s := range elb.Subnets { blocks = append(blocks, "subnet:"+aws.StringValue(s)) } blocks = append(blocks, "vpc:"+aws.StringValue(elb.VPCId)) tracker.blocks = blocks trackers = append(trackers, tracker) } return trackers, nil }
// firstStackEventWithFailure describes stack events and gets the latest event. func (c *cloudformationClient) firstStackEventWithFailure(stackName string, nextToken *string, failureStates map[string]bool) (*cloudformation.StackEvent, error) { response, err := c.client.DescribeStackEvents(&cloudformation.DescribeStackEventsInput{ StackName: aws.String(stackName), NextToken: nextToken, }) if err != nil { return nil, err } if len(response.StackEvents) == 0 { return nil, fmt.Errorf("Could not describe stack events") } if response.NextToken != nil { return c.firstStackEventWithFailure(stackName, response.NextToken, failureStates) } for i := len(response.StackEvents) - 1; i >= 0; i-- { event := response.StackEvents[i] log.WithFields(log.Fields{ "status": aws.StringValue(event.ResourceStatus), "reason": aws.StringValue(event.ResourceStatusReason), "id": aws.StringValue(event.EventId), "resourceType": aws.StringValue(event.ResourceType), }).Debug("Parsing event") if _, exists := failureStates[aws.StringValue(event.ResourceStatus)]; exists { return event, nil } } return nil, fmt.Errorf("Unable to find failure event in stack '%s'", stackName) }
// presignURL will presign the request by using SoureRegion to sign with. SourceRegion is not // sent to the service, and is only used to not have the SDKs parsing ARNs. func presignURL(r *request.Request, sourceRegion *string, newParams interface{}) *string { cfg := r.Config.Copy(aws.NewConfig(). WithEndpoint(""). WithRegion(aws.StringValue(sourceRegion))) clientInfo := r.ClientInfo resolved, err := r.Config.EndpointResolver.EndpointFor( clientInfo.ServiceName, aws.StringValue(cfg.Region), func(opt *endpoints.Options) { opt.DisableSSL = aws.BoolValue(cfg.DisableSSL) opt.UseDualStack = aws.BoolValue(cfg.UseDualStack) }, ) if err != nil { r.Error = err return nil } clientInfo.Endpoint = resolved.URL clientInfo.SigningRegion = resolved.SigningRegion // Presign a request with modified params req := request.New(*cfg, clientInfo, r.Handlers, r.Retryer, r.Operation, newParams, r.Data) req.Operation.HTTPMethod = "GET" uri, err := req.Presign(5 * time.Minute) // 5 minutes should be enough. if err != nil { // bubble error back up to original request r.Error = err return nil } // We have our URL, set it on params return &uri }