github.com/darmach/terratest@v0.34.8-0.20210517103231-80931f95e3ff/modules/aws/ec2-files.go (about) 1 package aws 2 3 import ( 4 "os" 5 "path/filepath" 6 7 "github.com/gruntwork-io/terratest/modules/files" 8 "github.com/gruntwork-io/terratest/modules/ssh" 9 "github.com/gruntwork-io/terratest/modules/testing" 10 "github.com/hashicorp/go-multierror" 11 ) 12 13 // RemoteFileSpecification describes which files you want to copy from your instances 14 type RemoteFileSpecification struct { 15 AsgNames []string //ASGs where our instances will be 16 RemotePathToFileFilter map[string][]string //A map of the files to fetch, where the keys are directories on the remote host and the values are filters for what files to fetch from the directory. The filters support bash-style wildcards. 17 UseSudo bool 18 SshUser string 19 KeyPair *Ec2Keypair 20 LocalDestinationDir string //base path where to store downloaded artifacts locally. The final path of each resource will include the ip of the host and the name of the immediate parent folder. 21 } 22 23 // FetchContentsOfFileFromInstance looks up the public IP address of the EC2 Instance with the given ID, connects to 24 // the Instance via SSH using the given username and Key Pair, fetches the contents of the file at the given path 25 // (using sudo if useSudo is true), and returns the contents of that file as a string. 26 func FetchContentsOfFileFromInstance(t testing.TestingT, awsRegion string, sshUserName string, keyPair *Ec2Keypair, instanceID string, useSudo bool, filePath string) string { 27 out, err := FetchContentsOfFileFromInstanceE(t, awsRegion, sshUserName, keyPair, instanceID, useSudo, filePath) 28 if err != nil { 29 t.Fatal(err) 30 } 31 return out 32 } 33 34 // FetchContentsOfFileFromInstanceE looks up the public IP address of the EC2 Instance with the given ID, connects to 35 // the Instance via SSH using the given username and Key Pair, fetches the contents of the file at the given path 36 // (using sudo if useSudo is true), and returns the contents of that file as a string. 37 func FetchContentsOfFileFromInstanceE(t testing.TestingT, awsRegion string, sshUserName string, keyPair *Ec2Keypair, instanceID string, useSudo bool, filePath string) (string, error) { 38 publicIp, err := GetPublicIpOfEc2InstanceE(t, instanceID, awsRegion) 39 if err != nil { 40 return "", err 41 } 42 43 host := ssh.Host{ 44 SshUserName: sshUserName, 45 SshKeyPair: keyPair.KeyPair, 46 Hostname: publicIp, 47 } 48 49 return ssh.FetchContentsOfFileE(t, host, useSudo, filePath) 50 } 51 52 // FetchContentsOfFilesFromInstance looks up the public IP address of the EC2 Instance with the given ID, connects to 53 // the Instance via SSH using the given username and Key Pair, fetches the contents of the files at the given paths 54 // (using sudo if useSudo is true), and returns a map from file path to the contents of that file as a string. 55 func FetchContentsOfFilesFromInstance(t testing.TestingT, awsRegion string, sshUserName string, keyPair *Ec2Keypair, instanceID string, useSudo bool, filePaths ...string) map[string]string { 56 out, err := FetchContentsOfFilesFromInstanceE(t, awsRegion, sshUserName, keyPair, instanceID, useSudo, filePaths...) 57 if err != nil { 58 t.Fatal(err) 59 } 60 return out 61 } 62 63 // FetchContentsOfFilesFromInstanceE looks up the public IP address of the EC2 Instance with the given ID, connects to 64 // the Instance via SSH using the given username and Key Pair, fetches the contents of the files at the given paths 65 // (using sudo if useSudo is true), and returns a map from file path to the contents of that file as a string. 66 func FetchContentsOfFilesFromInstanceE(t testing.TestingT, awsRegion string, sshUserName string, keyPair *Ec2Keypair, instanceID string, useSudo bool, filePaths ...string) (map[string]string, error) { 67 publicIp, err := GetPublicIpOfEc2InstanceE(t, instanceID, awsRegion) 68 if err != nil { 69 return nil, err 70 } 71 72 host := ssh.Host{ 73 SshUserName: sshUserName, 74 SshKeyPair: keyPair.KeyPair, 75 Hostname: publicIp, 76 } 77 78 return ssh.FetchContentsOfFilesE(t, host, useSudo, filePaths...) 79 } 80 81 // FetchContentsOfFileFromAsg looks up the EC2 Instances in the given ASG, looks up the public IPs of those EC2 82 // Instances, connects to each Instance via SSH using the given username and Key Pair, fetches the contents of the file 83 // at the given path (using sudo if useSudo is true), and returns a map from Instance ID to the contents of that file 84 // as a string. 85 func FetchContentsOfFileFromAsg(t testing.TestingT, awsRegion string, sshUserName string, keyPair *Ec2Keypair, asgName string, useSudo bool, filePath string) map[string]string { 86 out, err := FetchContentsOfFileFromAsgE(t, awsRegion, sshUserName, keyPair, asgName, useSudo, filePath) 87 if err != nil { 88 t.Fatal(err) 89 } 90 return out 91 } 92 93 // FetchContentsOfFileFromAsgE looks up the EC2 Instances in the given ASG, looks up the public IPs of those EC2 94 // Instances, connects to each Instance via SSH using the given username and Key Pair, fetches the contents of the file 95 // at the given path (using sudo if useSudo is true), and returns a map from Instance ID to the contents of that file 96 // as a string. 97 func FetchContentsOfFileFromAsgE(t testing.TestingT, awsRegion string, sshUserName string, keyPair *Ec2Keypair, asgName string, useSudo bool, filePath string) (map[string]string, error) { 98 instanceIDs, err := GetInstanceIdsForAsgE(t, asgName, awsRegion) 99 if err != nil { 100 return nil, err 101 } 102 103 instanceIdToContents := map[string]string{} 104 105 for _, instanceID := range instanceIDs { 106 contents, err := FetchContentsOfFileFromInstanceE(t, awsRegion, sshUserName, keyPair, instanceID, useSudo, filePath) 107 if err != nil { 108 return nil, err 109 } 110 instanceIdToContents[instanceID] = contents 111 } 112 113 return instanceIdToContents, err 114 } 115 116 // FetchContentsOfFilesFromAsg looks up the EC2 Instances in the given ASG, looks up the public IPs of those EC2 117 // Instances, connects to each Instance via SSH using the given username and Key Pair, fetches the contents of the files 118 // at the given paths (using sudo if useSudo is true), and returns a map from Instance ID to a map of file path to the 119 // contents of that file as a string. 120 func FetchContentsOfFilesFromAsg(t testing.TestingT, awsRegion string, sshUserName string, keyPair *Ec2Keypair, asgName string, useSudo bool, filePaths ...string) map[string]map[string]string { 121 out, err := FetchContentsOfFilesFromAsgE(t, awsRegion, sshUserName, keyPair, asgName, useSudo, filePaths...) 122 if err != nil { 123 t.Fatal(err) 124 } 125 return out 126 } 127 128 // FetchContentsOfFilesFromAsgE looks up the EC2 Instances in the given ASG, looks up the public IPs of those EC2 129 // Instances, connects to each Instance via SSH using the given username and Key Pair, fetches the contents of the files 130 // at the given paths (using sudo if useSudo is true), and returns a map from Instance ID to a map of file path to the 131 // contents of that file as a string. 132 func FetchContentsOfFilesFromAsgE(t testing.TestingT, awsRegion string, sshUserName string, keyPair *Ec2Keypair, asgName string, useSudo bool, filePaths ...string) (map[string]map[string]string, error) { 133 instanceIDs, err := GetInstanceIdsForAsgE(t, asgName, awsRegion) 134 if err != nil { 135 return nil, err 136 } 137 138 instanceIdToFilePathToContents := map[string]map[string]string{} 139 140 for _, instanceID := range instanceIDs { 141 contents, err := FetchContentsOfFilesFromInstanceE(t, awsRegion, sshUserName, keyPair, instanceID, useSudo, filePaths...) 142 if err != nil { 143 return nil, err 144 } 145 instanceIdToFilePathToContents[instanceID] = contents 146 } 147 148 return instanceIdToFilePathToContents, err 149 } 150 151 // FetchFilesFromInstance looks up the EC2 Instances in the given ASG, looks up the public IPs of those EC2 152 // Instances, connects to each Instance via SSH using the given username and Key Pair, downloads the files 153 // matching filenameFilters at the given remoteDirectory (using sudo if useSudo is true), and stores the files locally 154 // at localDirectory/<publicip>/<remoteFolderName> 155 func FetchFilesFromInstance(t testing.TestingT, awsRegion string, sshUserName string, keyPair *Ec2Keypair, instanceID string, useSudo bool, remoteDirectory string, localDirectory string, filenameFilters []string) { 156 err := FetchFilesFromInstanceE(t, awsRegion, sshUserName, keyPair, instanceID, useSudo, remoteDirectory, localDirectory, filenameFilters) 157 158 if err != nil { 159 t.Fatal(err) 160 } 161 } 162 163 // FetchFilesFromInstanceE looks up the EC2 Instances in the given ASG, looks up the public IPs of those EC2 164 // Instances, connects to each Instance via SSH using the given username and Key Pair, downloads the files 165 // matching filenameFilters at the given remoteDirectory (using sudo if useSudo is true), and stores the files locally 166 // at localDirectory/<publicip>/<remoteFolderName> 167 func FetchFilesFromInstanceE(t testing.TestingT, awsRegion string, sshUserName string, keyPair *Ec2Keypair, instanceID string, useSudo bool, remoteDirectory string, localDirectory string, filenameFilters []string) error { 168 publicIp, err := GetPublicIpOfEc2InstanceE(t, instanceID, awsRegion) 169 170 if err != nil { 171 return err 172 } 173 174 host := ssh.Host{ 175 Hostname: publicIp, 176 SshUserName: sshUserName, 177 SshKeyPair: keyPair.KeyPair, 178 } 179 180 finalLocalDestDir := filepath.Join(localDirectory, publicIp, filepath.Base(remoteDirectory)) 181 182 if !files.FileExists(finalLocalDestDir) { 183 os.MkdirAll(finalLocalDestDir, 0755) 184 } 185 186 scpOptions := ssh.ScpDownloadOptions{ 187 RemoteHost: host, 188 RemoteDir: remoteDirectory, 189 LocalDir: finalLocalDestDir, 190 FileNameFilters: filenameFilters, 191 } 192 193 return ssh.ScpDirFromE(t, scpOptions, useSudo) 194 } 195 196 // FetchFilesFromAsgs looks up the EC2 Instances in all the ASGs given in the RemoteFileSpecification, 197 // looks up the public IPs of those EC2 Instances, connects to each Instance via SSH using the given 198 // username and Key Pair, downloads the files matching filenameFilters at the given 199 // remoteDirectory (using sudo if useSudo is true), and stores the files locally at 200 // localDirectory/<publicip>/<remoteFolderName> 201 func FetchFilesFromAsgs(t testing.TestingT, awsRegion string, spec RemoteFileSpecification) { 202 err := FetchFilesFromAsgsE(t, awsRegion, spec) 203 204 if err != nil { 205 t.Fatal(err) 206 } 207 } 208 209 // FetchFilesFromAsgsE looks up the EC2 Instances in all the ASGs given in the RemoteFileSpecification, 210 // looks up the public IPs of those EC2 Instances, connects to each Instance via SSH using the given 211 // username and Key Pair, downloads the files matching filenameFilters at the given 212 // remoteDirectory (using sudo if useSudo is true), and stores the files locally at 213 // localDirectory/<publicip>/<remoteFolderName> 214 func FetchFilesFromAsgsE(t testing.TestingT, awsRegion string, spec RemoteFileSpecification) error { 215 var errorsOccurred = new(multierror.Error) 216 217 for _, curAsg := range spec.AsgNames { 218 for curRemoteDir, fileFilters := range spec.RemotePathToFileFilter { 219 220 instanceIDs, err := GetInstanceIdsForAsgE(t, curAsg, awsRegion) 221 if err != nil { 222 errorsOccurred = multierror.Append(errorsOccurred, err) 223 } else { 224 for _, instanceID := range instanceIDs { 225 err = FetchFilesFromInstanceE(t, awsRegion, spec.SshUser, spec.KeyPair, instanceID, spec.UseSudo, curRemoteDir, spec.LocalDestinationDir, fileFilters) 226 227 if err != nil { 228 errorsOccurred = multierror.Append(errorsOccurred, err) 229 } 230 } 231 } 232 } 233 } 234 return errorsOccurred.ErrorOrNil() 235 }