github.com/Cloud-Foundations/Dominator@v0.3.4/lib/awsutil/api.go (about) 1 package awsutil 2 3 import ( 4 "flag" 5 6 "github.com/Cloud-Foundations/Dominator/lib/log" 7 libtags "github.com/Cloud-Foundations/Dominator/lib/tags" 8 "github.com/aws/aws-sdk-go/aws" 9 "github.com/aws/aws-sdk-go/aws/session" 10 "github.com/aws/aws-sdk-go/service/ec2" 11 ) 12 13 var ( 14 awsConfigFile = flag.String( 15 "awsConfigFile", getConfigPath(), "Location of AWS config file") 16 awsCredentialsFile = flag.String( 17 "awsCredentialsFile", 18 getCredentialsPath(), 19 "Location of AWS credentials file") 20 ) 21 22 func CreateService(awsSession *session.Session, regionName string) *ec2.EC2 { 23 return ec2.New(awsSession, &aws.Config{Region: aws.String(regionName)}) 24 } 25 26 func CreateSession(accountProfileName string) (*session.Session, error) { 27 return session.NewSessionWithOptions(session.Options{ 28 Profile: accountProfileName, 29 SharedConfigState: session.SharedConfigEnable, 30 SharedConfigFiles: []string{ 31 *awsCredentialsFile, 32 *awsConfigFile, 33 }, 34 }) 35 } 36 37 // CredentialsOptions contains options for loading credentials 38 type CredentialsOptions struct { 39 40 // The path of the credentials file. 41 // If empty, defaults to to the same location that the LoadCredentials 42 // function uses. 43 CredentialsPath string 44 45 // The path of the config file. 46 // If empty, defaults to the same location that the LoadCredentials 47 // function uses. 48 ConfigPath string 49 } 50 51 // CredentialsStore records AWS credentials (IAM users and roles) for multiple 52 // accounts. The methods are safe to use concurrently. 53 type CredentialsStore struct { 54 accountNames []string 55 sessionMap map[string]*session.Session // Key: account name. 56 accountIdToName map[string]string // Key: account ID. 57 accountNameToId map[string]string // Key: account name. 58 accountRegions map[string][]string // Key: account name. 59 } 60 61 // LoadCredentials loads credentials from the aws credentials file and roles 62 // from the aws config file which may be used later. 63 // 64 // The location of the credentials file is determined using the following 65 // rules from highest to lowest precedence 1) -awsCredentialFile command line 66 // parameter. 2) AWS_CREDENTIAL_FILE environment variable. 67 // 3) ~/.aws/credentials 68 // 69 // The location of the config file is determines using the following rules 70 // from highest to lowest precedence 2) -awsConfigFile command line parameter 71 // 2) AWS_CONFIG_FILE environment variable. 3) ~/.aws/config 72 func LoadCredentials() (*CredentialsStore, error) { 73 return loadCredentials() 74 } 75 76 // TryLoadCredentials works like LoadCredentials but attempts to partially 77 // load the credentials in the presence of unloadable accounts. 78 // If the partial load is successful, unloadableAccounts contains the error 79 // encountered for each unloaded account. If partial load is unsuccessful, 80 // TryLoadCredentials returns nil, nil, err 81 func TryLoadCredentials() ( 82 store *CredentialsStore, unloadedAccounts map[string]error, err error) { 83 var options CredentialsOptions 84 return tryLoadCredentialsWithOptions(options.setDefaults()) 85 } 86 87 // TryLoadCredentialsWithOptions works just like TryLoadCredentials but 88 // allows caller to specify options for loading the credentials. 89 func TryLoadCredentialsWithOptions(options CredentialsOptions) ( 90 store *CredentialsStore, unloadedAccounts map[string]error, err error) { 91 return tryLoadCredentialsWithOptions(options.setDefaults()) 92 } 93 94 // AccountIdToName will return an account name given an account ID. 95 func (cs *CredentialsStore) AccountIdToName(accountId string) string { 96 return cs.accountIdToName[accountId] 97 } 98 99 // AccountNameToId will return an account ID given an account name. 100 func (cs *CredentialsStore) AccountNameToId(accountName string) string { 101 return cs.accountNameToId[accountName] 102 } 103 104 // ForEachEC2Target will iterate over a set of targets ((account,region) tuples) 105 // and will launch a goroutine calling targetFunc for each target. 106 // The list of targets to iterate over is given by targets and the list of 107 // targets to skip is given by skipList. An empty string for .AccountName is 108 // expanded to all available accounts and an empty string for .Region is 109 // expanded to all regions for an account. 110 // The number of goroutines is returned. If wait is true then ForEachTarget will 111 // wait for all the goroutines to complete, else it is the responsibility of the 112 // caller to wait for the goroutines to complete. 113 func (cs *CredentialsStore) ForEachEC2Target(targets TargetList, 114 skipList TargetList, 115 targetFunc func(awsService *ec2.EC2, accountName, regionName string, 116 logger log.Logger), 117 wait bool, logger log.Logger) (int, error) { 118 return cs.forEachEC2Target(targets, skipList, targetFunc, wait, logger) 119 } 120 121 // ForEachTarget will iterate over a set of targets ((account,region) tuples) 122 // and will launch a goroutine calling targetFunc for each target. 123 // The list of targets to iterate over is given by targets and the list of 124 // targets to skip is given by skipList. An empty string for .AccountName is 125 // expanded to all available accounts and an empty string for .Region is 126 // expanded to all regions for an account. 127 // The number of goroutines is returned. If wait is true then ForEachTarget will 128 // wait for all the goroutines to complete, else it is the responsibility of the 129 // caller to wait for the goroutines to complete. 130 func (cs *CredentialsStore) ForEachTarget(targets TargetList, 131 skipList TargetList, 132 targetFunc func(awsSession *session.Session, accountName, regionName string, 133 logger log.Logger), 134 wait bool, logger log.Logger) (int, error) { 135 return cs.forEachTarget(targets, skipList, targetFunc, wait, logger) 136 } 137 138 // GetSessionForAccount will return the session credentials available for an 139 // account. The name of the account should be given by accountName. 140 // A *session.Session is returned which may be used to bind to AWS services 141 // (i.e. EC2). 142 func (cs *CredentialsStore) GetSessionForAccount( 143 accountName string) *session.Session { 144 return cs.sessionMap[accountName] 145 } 146 147 // GetEC2Service will get an EC2 service handle for an account and region. 148 func (cs *CredentialsStore) GetEC2Service(accountName, 149 regionName string) *ec2.EC2 { 150 return CreateService(cs.GetSessionForAccount(accountName), regionName) 151 } 152 153 // ListAccountsWithCredentials will list all accounts for which credentials 154 // are available. 155 func (cs *CredentialsStore) ListAccountsWithCredentials() []string { 156 return cs.accountNames 157 } 158 159 // ListRegionsForAccount will return all the regions available to an account. 160 func (cs *CredentialsStore) ListRegionsForAccount(accountName string) []string { 161 return cs.accountRegions[accountName] 162 } 163 164 func ForEachTarget(targets TargetList, skipList TargetList, 165 targetFunc func(awsService *ec2.EC2, accountName, regionName string, 166 logger log.Logger), 167 logger log.Logger) (int, error) { 168 return forEachTarget(targets, skipList, targetFunc, logger) 169 } 170 171 func GetLocalRegion() (string, error) { 172 return getLocalRegion() 173 } 174 175 func ListAccountNames() ([]string, error) { 176 var options CredentialsOptions 177 return listAccountNames(options.setDefaults()) 178 } 179 180 func ListAccountNamesWithOptions(options CredentialsOptions) ([]string, error) { 181 return listAccountNames(options.setDefaults()) 182 } 183 184 func ListRegions(awsService *ec2.EC2) ([]string, error) { 185 return listRegions(awsService) 186 } 187 188 func MakeFilterFromTag(tag libtags.Tag) *ec2.Filter { 189 return makeFilterFromTag(tag) 190 } 191 192 func CreateTagsFromList(list []*ec2.Tag) libtags.Tags { 193 return createTagsFromList(list) 194 } 195 196 func MakeFiltersFromTags(tags libtags.Tags) []*ec2.Filter { 197 return makeFiltersFromTags(tags) 198 } 199 200 type Target struct { 201 AccountName string 202 Region string 203 } 204 205 type TargetList []Target 206 207 func (list *TargetList) String() string { 208 return list.string() 209 } 210 211 func (list *TargetList) Set(value string) error { 212 return list.set(value) 213 }