github.com/sentienttechnologies/studio-go-runner@v0.0.0-20201118202441-6d21f2ced8ee/internal/runner/aws.go (about) 1 // Copyright 2018-2020 (c) Cognizant Digital Business, Evolutionary AI. All rights reserved. Issued under the Apache 2.0 License. 2 3 package runner 4 5 // This file contains the implementation of functions related to AWS. 6 // 7 // Especially functions related to the credentials file handling 8 9 import ( 10 "bufio" 11 "bytes" 12 "os" 13 "path/filepath" 14 "strings" 15 16 "github.com/aws/aws-sdk-go/aws/credentials" 17 18 "github.com/go-stack/stack" 19 "github.com/jjeffery/kv" // MIT License 20 ) 21 22 // AWSCred is used to encapsulate the credentials that are to be used to access an AWS resource 23 // suhc as an S3 bucket for example. 24 // 25 type AWSCred struct { 26 Project string 27 Region string 28 Creds *credentials.Credentials 29 } 30 31 // AWSExtractCreds can be used to populate a set of credentials from a pair of config and 32 // credentials files typicall found in the ~/.aws directory by AWS clients 33 // 34 func AWSExtractCreds(filenames []string) (cred *AWSCred, err kv.Error) { 35 36 cred = &AWSCred{ 37 Project: "aws_" + filepath.Base(filepath.Dir(filenames[0])), 38 } 39 40 credsDone := false 41 42 // AWS Does not read the region automatically from the config so lets read it here 43 for _, aFile := range filenames { 44 wasConfig := func() bool { 45 f, err := os.Open(filepath.Clean(aFile)) 46 if err != nil { 47 return false 48 } 49 if len(cred.Region) == 0 { 50 scan := bufio.NewScanner(f) 51 for scan.Scan() { 52 line := scan.Text() 53 line = strings.Replace(line, " ", "", -1) 54 if strings.HasPrefix(strings.ToLower(line), "region=") { 55 tokens := strings.SplitN(line, "=", 2) 56 cred.Region = tokens[1] 57 return true 58 } 59 } 60 } 61 62 f.Close() 63 return false 64 }() 65 66 if !credsDone && !wasConfig { 67 cred.Creds = credentials.NewSharedCredentials(aFile, "default") 68 credsDone = true 69 } 70 } 71 72 if len(cred.Region) == 0 { 73 return nil, kv.NewError("none of the supplied files defined a region").With("stack", stack.Trace().TrimRuntime()).With("files", filenames) 74 } 75 76 if !credsDone { 77 return nil, kv.NewError("credentials never loaded").With("stack", stack.Trace().TrimRuntime()).With("files", filenames) 78 } 79 return cred, nil 80 } 81 82 // IsAWS can detect if pods running within a Kubernetes cluster are actually being hosted on an EC2 instance 83 // 84 func IsAWS() (aws bool, err kv.Error) { 85 fn := "/sys/devices/virtual/dmi/id/product_uuid" 86 uuidFile, errGo := os.Open(fn) 87 if errGo != nil { 88 return false, kv.Wrap(errGo).With("stack", stack.Trace().TrimRuntime()).With("file", fn) 89 } 90 defer uuidFile.Close() 91 92 signature := []byte{'E', 'C', '2'} 93 buffer := make([]byte, len(signature)) 94 95 cnt, errGo := uuidFile.Read(buffer) 96 if errGo != nil { 97 return false, kv.Wrap(errGo).With("stack", stack.Trace().TrimRuntime()).With("file", fn) 98 } 99 if cnt != len(signature) { 100 return false, kv.NewError("invalid signature"). 101 With("file", fn, "buffer", string(buffer), "cnt", cnt). 102 With("stack", stack.Trace().TrimRuntime()) 103 } 104 105 return 0 == bytes.Compare(buffer, signature), nil 106 }