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  }