From 11824666eece2641c79fc6489402ae0f70b39141 Mon Sep 17 00:00:00 2001 From: Andrew Roth Date: Mon, 1 Nov 2021 12:22:23 -0700 Subject: [PATCH] Run `pre-commit run -a` on the codebase --- README.md | 66 +++--- docs/asciinema/.gitignore | 2 +- docs/asciinema/README.md | 2 +- docs/asciinema/Vagrantfile | 4 +- docs/asciinema/asciinema-org | 2 +- docs/asciinema/asciinema.sh | 10 +- docs/asciinema/delete.tmpl.curl | 2 +- docs/asciinema/get.tmpl.curl | 2 +- docs/asciinema/scenarios/asciinema-demo.exp | 1 - docs/components.md | 2 +- docs/ironbank.md | 4 +- docs/supported-oses.md | 2 +- docs/workstation.md | 8 +- examples/README.md | 2 +- examples/game/README.md | 4 +- test/e2e/common.go | 226 ++++++++++---------- test/e2e/e2e_example_game_test.go | 136 ++++++------ test/e2e/e2e_general_cli_test.go | 152 ++++++------- 18 files changed, 313 insertions(+), 314 deletions(-) diff --git a/README.md b/README.md index 89c3fb00c4..5006c9d2c5 100644 --- a/README.md +++ b/README.md @@ -31,14 +31,14 @@ Zarf runs on [a bunch of operating systems](./docs/supported-oses.md) and aims t **Get Started** - + _Using Zarf_ Experience just how easy it is to go from _**zero** to **chainsaw wielding hero** (of the Kubernetes cluster)_ using Zarf! - + @@ -51,11 +51,11 @@ Zarf runs on [a bunch of operating systems](./docs/supported-oses.md) and aims t - + **Add Logging** _Zarf components_ - + @@ -73,16 +73,16 @@ Zarf runs on [a bunch of operating systems](./docs/supported-oses.md) and aims t - + **Roll Your Own** _Custom packages_ - + Once you're comfortable with the basic workflow & able to deploy _someone else's_ Zarf deployment packages, it's time to roll your own. Here's how. - + @@ -113,14 +113,14 @@ Zarf runs on [a bunch of operating systems](./docs/supported-oses.md) and aims t **Simple Applications** - + _Appliance Mode_ If want to "run a Kubernetes app" but aren't into hand-rolling a cluster just for it, Zarf can help. Here's how, and _why_ you might want to. - + @@ -133,16 +133,16 @@ Zarf runs on [a bunch of operating systems](./docs/supported-oses.md) and aims t - + **Disconnected GitOps** _The Utility Cluster_ - + Zarf overcomes the "the Air Gap problem" using a Kubernetes cluster (and k8s-native tooling) for the care & feeding of _other k8s clusters_. - + Here's how it works and what ops/support looks like. @@ -175,10 +175,10 @@ Zarf runs on [a bunch of operating systems](./docs/supported-oses.md) and aims t **Workstation Setup** - + - + Thinking about hacking on the Zarf binary itself? Or, perhaps you want to run the examples in an isolated environment (the same way we do)? Get your machine setup _just right_ using these instructions! @@ -193,12 +193,12 @@ Zarf runs on [a bunch of operating systems](./docs/supported-oses.md) and aims t - + **Build Your First Zarf** - + - + You've got a development workstation setup, so... now what? Why not _build your own Zarf_? Step-by-step instructions, here. @@ -213,12 +213,12 @@ Zarf runs on [a bunch of operating systems](./docs/supported-oses.md) and aims t - + **Contribution Guide** - + - + As with most collaborative efforts there are guidelines for contributing to the project. Find out what they are & how to make them work, here. @@ -251,12 +251,12 @@ Zarf runs on [a bunch of operating systems](./docs/supported-oses.md) and aims t **Supported OSes** - + - + Zarf is intended to run on a variety of Operating Systems—you can find out which _and_ discover how to take Zarf for a test-drive (in a VM of your favorite flavor) by clicking the link! - + @@ -271,14 +271,14 @@ Zarf runs on [a bunch of operating systems](./docs/supported-oses.md) and aims t **Zarf Components** - + - + Need to understand what's happening in your cluster? Zarf can give you visibility by injecting a _Logging_ component. Looking for some additional CLI tooling? Install the _Management_ component. - + Find out all the other stuff Zarf offers, here. - + @@ -293,12 +293,12 @@ Zarf runs on [a bunch of operating systems](./docs/supported-oses.md) and aims t **Usage Examples** - + - + There are a bunch of interesting ways to use Zarf beyond "space-marine-ing" your way through _the_ pixel demon invasion. Browse our examples directory to find out what other neat things are available. - + @@ -311,16 +311,16 @@ Zarf runs on [a bunch of operating systems](./docs/supported-oses.md) and aims t - + **Iron Bank**
_Hardened image registry_ - + Zarf can build deployment packages using images pulled from pretty much anywhere... but for gov't-approved & "[hardened](https://en.wikipedia.org/wiki/Hardening_(computing))" container images check out Platform One's [Iron Bank](https://p1.dso.mil/#/products/iron-bank/). - + diff --git a/docs/asciinema/.gitignore b/docs/asciinema/.gitignore index 169f8fc36f..95ddfc5472 100644 --- a/docs/asciinema/.gitignore +++ b/docs/asciinema/.gitignore @@ -1,3 +1,3 @@ recordings/ .config/ -*.log \ No newline at end of file +*.log diff --git a/docs/asciinema/README.md b/docs/asciinema/README.md index 15f2429ff6..837fc5eda2 100644 --- a/docs/asciinema/README.md +++ b/docs/asciinema/README.md @@ -78,7 +78,7 @@ When you run `asciinema` commands, if you do not already have an `install-id` fi If you need recordings to stick around and be listed in a specific group, however—and in this case you do—then you'll need access to an install id that has been registered with Zarf's account on asciinema.org. > _**Dig in!**_ -> +> > Go ahead and have a look at the asciinema [usage page](https://asciinema.org/docs/usage) (under the "auth" heading) if you're interested in more detail / background on this topic.   diff --git a/docs/asciinema/Vagrantfile b/docs/asciinema/Vagrantfile index 79de28a689..34b25f40da 100644 --- a/docs/asciinema/Vagrantfile +++ b/docs/asciinema/Vagrantfile @@ -14,10 +14,10 @@ Vagrant.configure("2") do |config| config.vm.synced_folder '.', '/vagrant', disabled: true config.vm.synced_folder '../..', '/zarf', SharedFoldersEnableSymlinksCreate: false config.vm.synced_folder'./.config/asciinema', '/root/.config/asciinema', - SharedFoldersEnableSymlinksCreate: false, + SharedFoldersEnableSymlinksCreate: false, owner: 'root', group: 'root' config.vm.synced_folder'~/.docker', '/root/.docker', - SharedFoldersEnableSymlinksCreate: false, + SharedFoldersEnableSymlinksCreate: false, owner: 'root', group: 'root' config.ssh.insert_key = false diff --git a/docs/asciinema/asciinema-org b/docs/asciinema/asciinema-org index 5950224295..5029fda1b8 100644 --- a/docs/asciinema/asciinema-org +++ b/docs/asciinema/asciinema-org @@ -1 +1 @@ -https://asciinema.org/~barrett \ No newline at end of file +https://asciinema.org/~barrett diff --git a/docs/asciinema/asciinema.sh b/docs/asciinema/asciinema.sh index 1f01620164..fd6f10758f 100755 --- a/docs/asciinema/asciinema.sh +++ b/docs/asciinema/asciinema.sh @@ -27,7 +27,7 @@ function help() { echo "" } -# executes (and records) a given scenario file's terminal session +# executes (and records) a given scenario file's terminal session function run() { local fname="${1##*/}" local fpath="$SCENARIOS/$fname" @@ -165,7 +165,7 @@ function sub() { local lines="$( printf '%.0s- ' {1..12} )" local found="$( cat - | paste -d '\t' $lines )" # <-- reads stdin! local clean="$( echo "$found" | tr -s ' ' | sed -E 's/: \t/: -\t/g' )" - + echo "$clean" | while IFS= read -r c ; do local sub="$( echo "$c" | grep -Po 'sub : \K[^\t]*' )" if [ "$sub" = "no" ] ; then continue ; fi @@ -238,7 +238,7 @@ function zap() { plan="$plan$r"$'\t'"$verdict"$'\n' done <<< "$recordings" plan="${plan::-1}" - + # act on the plan? echo "" echo "$plan" @@ -259,7 +259,7 @@ function zap() { echo "$plan" | grep -P 'delete$' | while IFS= read -r p ; do local path="$( echo "$p" | awk -F $'\t' '{print $2}' )" - + # secure a csrf token via "get" request local get="$( cat "$HERE/get.tmpl.curl" \ | sed 's|{{path}}|'"$path"'|g' \ @@ -300,7 +300,7 @@ case "$cmd" in "run") if [ "$#" -lt 1 ] || [ "$1" = "all" ] ; then run_all ; else run "$@" ; fi ;; - + "pub") if [ "$#" -lt 1 ] || [ "$1" = "all" ] ; then pub_all ; else pub "$@" ; fi ;; diff --git a/docs/asciinema/delete.tmpl.curl b/docs/asciinema/delete.tmpl.curl index 6444ad8a88..08582e6e4a 100644 --- a/docs/asciinema/delete.tmpl.curl +++ b/docs/asciinema/delete.tmpl.curl @@ -17,4 +17,4 @@ curl 'https://asciinema.org{{path}}' \ -H 'accept-language: en-US,en;q=0.9' \ -H 'cookie: auth_token={{auth_token}}; _asciinema_key={{_asciinema_key}}' \ --data-raw '_csrf_token={{csrf}}&_method=delete' \ - --compressed \ No newline at end of file + --compressed diff --git a/docs/asciinema/get.tmpl.curl b/docs/asciinema/get.tmpl.curl index 22f4c6330a..8b2af2b36e 100644 --- a/docs/asciinema/get.tmpl.curl +++ b/docs/asciinema/get.tmpl.curl @@ -13,4 +13,4 @@ curl 'https://asciinema.org{{path}}' \ -H 'referer: {{account}}' \ -H 'accept-language: en-US,en;q=0.9' \ -H 'cookie: auth_token={{auth_token}}; _asciinema_key={{_asciinema_key}}' \ - --compressed \ No newline at end of file + --compressed diff --git a/docs/asciinema/scenarios/asciinema-demo.exp b/docs/asciinema/scenarios/asciinema-demo.exp index 189c3cae49..9087242a59 100755 --- a/docs/asciinema/scenarios/asciinema-demo.exp +++ b/docs/asciinema/scenarios/asciinema-demo.exp @@ -55,4 +55,3 @@ comment "Great. Let's say hi." do "./zarf help" comment "Perfect!" - diff --git a/docs/components.md b/docs/components.md index 868362d972..519a1d5a94 100644 --- a/docs/components.md +++ b/docs/components.md @@ -39,4 +39,4 @@ These optional components are listed below along with the "magic strings" you pa ## Further reading -For more detail—like which components are on/off by default—there's no better place to check than the source: [zarf.yaml](../zarf.yaml). \ No newline at end of file +For more detail—like which components are on/off by default—there's no better place to check than the source: [zarf.yaml](../zarf.yaml). diff --git a/docs/ironbank.md b/docs/ironbank.md index 14510c4da5..8ab35a81cf 100644 --- a/docs/ironbank.md +++ b/docs/ironbank.md @@ -41,7 +41,7 @@ In order to figure out what your personal "CLI secret" is you first need to log Then, pop open your "User Profile" and copy down your `Username` and `CLI secret`. > _**Take note**_ -> +> > You need your **Username** specifically—trying to log Zarf into Iron Bank using Email will not work!   @@ -58,4 +58,4 @@ Zarf will dump an auth file into your user home directory—`$HOME/.docker/c > _**Beware!**_ > -> This file contains your personal credentials for interacting with Iron Bank and _could be used to impersonate you_. Make sure to keep this file safe! \ No newline at end of file +> This file contains your personal credentials for interacting with Iron Bank and _could be used to impersonate you_. Make sure to keep this file safe! diff --git a/docs/supported-oses.md b/docs/supported-oses.md index 2a150ba684..4861ad5643 100644 --- a/docs/supported-oses.md +++ b/docs/supported-oses.md @@ -81,4 +81,4 @@ Closing out the demo environment is _also_ a single command: make vm-destroy ``` -This will shutdown & destroy _all_ the demo VM instances it can find. Easy-peasy—nice and clean. \ No newline at end of file +This will shutdown & destroy _all_ the demo VM instances it can find. Easy-peasy—nice and clean. diff --git a/docs/workstation.md b/docs/workstation.md index 911c5b3099..380ac67920 100644 --- a/docs/workstation.md +++ b/docs/workstation.md @@ -18,15 +18,15 @@ The simplest path to Zarf is to download a pre-built release and execute it on y 1. Download: - The zarf cluster initialization package: `zarf-init.tar.zst`. - + - The appropriate zarf binary for your system (choose _one_): | system | binary | - | --- | --- | + | --- | --- | | Linux (64bit) | `zarf` | | Intel-based Mac | `zarf-mac-intel` | | [Apple-based Mac](https://support.apple.com/en-us/HT211814) | `zarf-mac-apple` | - + - (optional) The checksum file: `zarf.sha256`. 1. (optional) Verify integrity of the downloaded files by validating their hashes—more about that ( [here](https://en.wikipedia.org/wiki/Checksum) / [here](https://help.ubuntu.com/community/HowToSHA256SUM) ) if you're interested. From _the directory holding your files_, run: @@ -53,7 +53,7 @@ chmod +x ./zarf && ./zarf help ``` > _**Take note**_ -> +> > Commands run this way _will_ make changes to your current system / environment! > >This is the expected usage pattern for production but for demonstration / development & test there are better, **virtual machine**-isolated ways to run Zarf. Keep reading to find out how to get setup for those! diff --git a/examples/README.md b/examples/README.md index cd122a3ad3..b0fc4f458c 100644 --- a/examples/README.md +++ b/examples/README.md @@ -4,4 +4,4 @@ The Zarf examples demonstrate different ways to utilize Zarf in your environment To test create a virtual area to test all examples, you can run `make all` or `make vm-init` if you've already run the examples before. Run `make vm-destroy` to clean up. -> **NOTE**: This tool utilizes software pulled from multiple sources and _some_ of them require authenticated access! Check the examples themselves for the specific accounts / logins required! \ No newline at end of file +> **NOTE**: This tool utilizes software pulled from multiple sources and _some_ of them require authenticated access! Check the examples themselves for the specific accounts / logins required! diff --git a/examples/game/README.md b/examples/game/README.md index 4ba3e858c5..a00c291eec 100644 --- a/examples/game/README.md +++ b/examples/game/README.md @@ -73,7 +73,7 @@ zarf init Answer the follow-on prompts as appropriate for your machine configuration & give it a few seconds to run. Congratulations! Your machine is now a single node k8s cluster! - + > _**Note**_ > > Zarf supports fire-and-forget installs too! Give `zarf init --help` a call for more details on that. @@ -237,4 +237,4 @@ It only takes a couple moments for the _entire Zarf cluster_ to disappear— - https://www.reddit.com/r/programming/comments/nap4pt/dos_gaming_in_docker/ -- https://earthly.dev/blog/dos-gaming-in-docker/ \ No newline at end of file +- https://earthly.dev/blog/dos-gaming-in-docker/ diff --git a/test/e2e/common.go b/test/e2e/common.go index 04ae0be542..54dfdf8a19 100644 --- a/test/e2e/common.go +++ b/test/e2e/common.go @@ -1,139 +1,139 @@ package test import ( - "bufio" - "encoding/base64" - "fmt" - "github.com/gruntwork-io/terratest/modules/random" - "github.com/gruntwork-io/terratest/modules/retry" - teststructure "github.com/gruntwork-io/terratest/modules/test-structure" - "github.com/stretchr/testify/require" - "io/ioutil" - "os" - "testing" - "time" - - "github.com/gruntwork-io/terratest/modules/aws" - "github.com/gruntwork-io/terratest/modules/ssh" - "github.com/gruntwork-io/terratest/modules/terraform" + "bufio" + "encoding/base64" + "fmt" + "github.com/gruntwork-io/terratest/modules/random" + "github.com/gruntwork-io/terratest/modules/retry" + teststructure "github.com/gruntwork-io/terratest/modules/test-structure" + "github.com/stretchr/testify/require" + "io/ioutil" + "os" + "testing" + "time" + + "github.com/gruntwork-io/terratest/modules/aws" + "github.com/gruntwork-io/terratest/modules/ssh" + "github.com/gruntwork-io/terratest/modules/terraform" ) func teardown(t *testing.T, tmpFolder string) { - keyPair := teststructure.LoadEc2KeyPair(t, tmpFolder) - aws.DeleteEC2KeyPair(t, keyPair) + keyPair := teststructure.LoadEc2KeyPair(t, tmpFolder) + aws.DeleteEC2KeyPair(t, keyPair) - terraformOptions := teststructure.LoadTerraformOptions(t, tmpFolder) - terraform.Destroy(t, terraformOptions) + terraformOptions := teststructure.LoadTerraformOptions(t, tmpFolder) + terraform.Destroy(t, terraformOptions) } func setup(t *testing.T, tmpFolder string) { - terraformOptions, keyPair, err := configureTerraformOptions(t, tmpFolder) - require.NoError(t, err) + terraformOptions, keyPair, err := configureTerraformOptions(t, tmpFolder) + require.NoError(t, err) - // Save the options and key pair so later test stages can use them - teststructure.SaveTerraformOptions(t, tmpFolder, terraformOptions) - teststructure.SaveEc2KeyPair(t, tmpFolder, keyPair) + // Save the options and key pair so later test stages can use them + teststructure.SaveTerraformOptions(t, tmpFolder, terraformOptions) + teststructure.SaveEc2KeyPair(t, tmpFolder, keyPair) - // This will run `terraform init` and `terraform apply` and fail the test if there are any errors - terraform.InitAndApply(t, terraformOptions) + // This will run `terraform init` and `terraform apply` and fail the test if there are any errors + terraform.InitAndApply(t, terraformOptions) } func configureTerraformOptions(t *testing.T, tmpFolder string) (*terraform.Options, *aws.Ec2Keypair, error) { - // A unique ID we can use to namespace resources so we don't clash with anything already in the AWS account or - // tests running in parallel - uniqueID := random.UniqueId() - namespace := "zarf" - stage := "terratest" - name := fmt.Sprintf("e2e-%s", uniqueID) - - // Get the region to use from the system's environment - awsRegion, err := getAwsRegion() - if err != nil { - return nil, nil, err - } - - instanceType := "t3a.large" - - // Create an EC2 KeyPair that we can use for SSH access - keyPairName := fmt.Sprintf("%s-%s-%s", namespace, stage, name) - keyPair := aws.CreateAndImportEC2KeyPair(t, awsRegion, keyPairName) - - // Construct the terraform options with default retryable errors to handle the most common retryable errors in - // terraform testing. - terraformOptions := terraform.WithDefaultRetryableErrors(t, &terraform.Options{ - // The path to where our Terraform code is located - TerraformDir: tmpFolder, - - // Variables to pass to our Terraform code using -var options - Vars: map[string]interface{}{ - "aws_region": awsRegion, - "namespace": namespace, - "stage": stage, - "name": name, - "instance_type": instanceType, - "key_pair_name": keyPairName, - }, - }) - - return terraformOptions, keyPair, nil + // A unique ID we can use to namespace resources so we don't clash with anything already in the AWS account or + // tests running in parallel + uniqueID := random.UniqueId() + namespace := "zarf" + stage := "terratest" + name := fmt.Sprintf("e2e-%s", uniqueID) + + // Get the region to use from the system's environment + awsRegion, err := getAwsRegion() + if err != nil { + return nil, nil, err + } + + instanceType := "t3a.large" + + // Create an EC2 KeyPair that we can use for SSH access + keyPairName := fmt.Sprintf("%s-%s-%s", namespace, stage, name) + keyPair := aws.CreateAndImportEC2KeyPair(t, awsRegion, keyPairName) + + // Construct the terraform options with default retryable errors to handle the most common retryable errors in + // terraform testing. + terraformOptions := terraform.WithDefaultRetryableErrors(t, &terraform.Options{ + // The path to where our Terraform code is located + TerraformDir: tmpFolder, + + // Variables to pass to our Terraform code using -var options + Vars: map[string]interface{}{ + "aws_region": awsRegion, + "namespace": namespace, + "stage": stage, + "name": name, + "instance_type": instanceType, + "key_pair_name": keyPairName, + }, + }) + + return terraformOptions, keyPair, nil } // syncFileToRemoteServer uses SCP to sync a file from source to destination. `destPath` can be absolute or relative to // the SSH user's home directory. It has to be in a directory that the SSH user is allowed to write to. func syncFileToRemoteServer(t *testing.T, terraformOptions *terraform.Options, keyPair *aws.Ec2Keypair, sshUsername string, srcPath string, destPath string, chmod string) { - // Run `terraform output` to get the value of an output variable - publicInstanceIP := terraform.Output(t, terraformOptions, "public_instance_ip") - - // We're going to try to SSH to the instance IP, using the Key Pair we created earlier, and the user "ubuntu", - // as we know the Instance is running an Ubuntu AMI that has such a user - host := ssh.Host{ - Hostname: publicInstanceIP, - SshKeyPair: keyPair.KeyPair, - SshUserName: sshUsername, - } - - // It can take a minute or so for the Instance to boot up, so retry a few times - maxRetries := 15 - timeBetweenRetries, err := time.ParseDuration("5s") - require.NoError(t, err) - - // Wait for the instance to be ready - _, err = retry.DoWithRetryE(t, "Wait for the instance to be ready", maxRetries, timeBetweenRetries, func() (string, error){ - _, err := ssh.CheckSshCommandE(t, host, "whoami") - if err != nil { - return "", err - } - return "", nil - }) - require.NoError(t, err) - - // Create the folder structure - output, err := ssh.CheckSshCommandE(t, host,fmt.Sprintf("bash -c 'install -m 644 -D /dev/null \"%s\"'", destPath)) - require.NoError(t, err, output) - - // The ssh lib only supports sending strings so we'll base64encode it first - f, err := os.Open(srcPath) - require.NoError(t, err) - reader := bufio.NewReader(f) - content, err := ioutil.ReadAll(reader) - require.NoError(t, err) - encodedContent := base64.StdEncoding.EncodeToString(content) - err = ssh.ScpFileToE(t, host, 0600, fmt.Sprintf("%s.b64", destPath), encodedContent) - require.NoError(t, err) - output, err = ssh.CheckSshCommandE(t, host, fmt.Sprintf("base64 -d \"%s.b64\" > \"%s\" && chmod \"%s\" \"%s\"", destPath, destPath, chmod, destPath)) - require.NoError(t, err, output) + // Run `terraform output` to get the value of an output variable + publicInstanceIP := terraform.Output(t, terraformOptions, "public_instance_ip") + + // We're going to try to SSH to the instance IP, using the Key Pair we created earlier, and the user "ubuntu", + // as we know the Instance is running an Ubuntu AMI that has such a user + host := ssh.Host{ + Hostname: publicInstanceIP, + SshKeyPair: keyPair.KeyPair, + SshUserName: sshUsername, + } + + // It can take a minute or so for the Instance to boot up, so retry a few times + maxRetries := 15 + timeBetweenRetries, err := time.ParseDuration("5s") + require.NoError(t, err) + + // Wait for the instance to be ready + _, err = retry.DoWithRetryE(t, "Wait for the instance to be ready", maxRetries, timeBetweenRetries, func() (string, error) { + _, err := ssh.CheckSshCommandE(t, host, "whoami") + if err != nil { + return "", err + } + return "", nil + }) + require.NoError(t, err) + + // Create the folder structure + output, err := ssh.CheckSshCommandE(t, host, fmt.Sprintf("bash -c 'install -m 644 -D /dev/null \"%s\"'", destPath)) + require.NoError(t, err, output) + + // The ssh lib only supports sending strings so we'll base64encode it first + f, err := os.Open(srcPath) + require.NoError(t, err) + reader := bufio.NewReader(f) + content, err := ioutil.ReadAll(reader) + require.NoError(t, err) + encodedContent := base64.StdEncoding.EncodeToString(content) + err = ssh.ScpFileToE(t, host, 0600, fmt.Sprintf("%s.b64", destPath), encodedContent) + require.NoError(t, err) + output, err = ssh.CheckSshCommandE(t, host, fmt.Sprintf("base64 -d \"%s.b64\" > \"%s\" && chmod \"%s\" \"%s\"", destPath, destPath, chmod, destPath)) + require.NoError(t, err, output) } // getAwsRegion returns the desired AWS region to use by first checking the env var AWS_REGION, then checking // AWS_DEFAULT_REGION if AWS_REGION isn't set. If neither is set it returns an error func getAwsRegion() (string, error) { - val, present := os.LookupEnv("AWS_REGION") - if !present { - val, present = os.LookupEnv("AWS_DEFAULT_REGION") - } - if !present { - return "", fmt.Errorf("expected either AWS_REGION or AWS_DEFAULT_REGION env var to be set, but they were not") - } else { - return val, nil - } + val, present := os.LookupEnv("AWS_REGION") + if !present { + val, present = os.LookupEnv("AWS_DEFAULT_REGION") + } + if !present { + return "", fmt.Errorf("expected either AWS_REGION or AWS_DEFAULT_REGION env var to be set, but they were not") + } else { + return val, nil + } } diff --git a/test/e2e/e2e_example_game_test.go b/test/e2e/e2e_example_game_test.go index 364a06b851..60fa081550 100644 --- a/test/e2e/e2e_example_game_test.go +++ b/test/e2e/e2e_example_game_test.go @@ -1,86 +1,86 @@ package test import ( - "fmt" - "github.com/gruntwork-io/terratest/modules/aws" - "github.com/gruntwork-io/terratest/modules/ssh" - "github.com/gruntwork-io/terratest/modules/terraform" - teststructure "github.com/gruntwork-io/terratest/modules/test-structure" - "github.com/stretchr/testify/require" - "testing" + "fmt" + "github.com/gruntwork-io/terratest/modules/aws" + "github.com/gruntwork-io/terratest/modules/ssh" + "github.com/gruntwork-io/terratest/modules/terraform" + teststructure "github.com/gruntwork-io/terratest/modules/test-structure" + "github.com/stretchr/testify/require" + "testing" ) func TestE2eExampleGame(t *testing.T) { - t.Parallel() + t.Parallel() - // Our SSH username, will change based on which AMI we use - username := "ubuntu" + // Our SSH username, will change based on which AMI we use + username := "ubuntu" - // Copy the terraform folder to a temp directory so we can run multiple tests in parallel - tmpFolder := teststructure.CopyTerraformFolderToTemp(t, "..", "tf/public-ec2-instance") + // Copy the terraform folder to a temp directory so we can run multiple tests in parallel + tmpFolder := teststructure.CopyTerraformFolderToTemp(t, "..", "tf/public-ec2-instance") - // At the end of the test, run `terraform destroy` to clean up any resources that were created - defer teststructure.RunTestStage(t, "TEARDOWN", func() { - teardown(t, tmpFolder) - }) + // At the end of the test, run `terraform destroy` to clean up any resources that were created + defer teststructure.RunTestStage(t, "TEARDOWN", func() { + teardown(t, tmpFolder) + }) - // Deploy the terraform infra - teststructure.RunTestStage(t, "SETUP", func() { - setup(t, tmpFolder) - }) + // Deploy the terraform infra + teststructure.RunTestStage(t, "SETUP", func() { + setup(t, tmpFolder) + }) - // Upload the Zarf artifacts - teststructure.RunTestStage(t, "UPLOAD", func() { - terraformOptions := teststructure.LoadTerraformOptions(t, tmpFolder) - keyPair := teststructure.LoadEc2KeyPair(t, tmpFolder) + // Upload the Zarf artifacts + teststructure.RunTestStage(t, "UPLOAD", func() { + terraformOptions := teststructure.LoadTerraformOptions(t, tmpFolder) + keyPair := teststructure.LoadEc2KeyPair(t, tmpFolder) - syncFileToRemoteServer(t, terraformOptions, keyPair, username, "../../build/zarf", fmt.Sprintf("/home/%s/build/zarf", username), "0700") - syncFileToRemoteServer(t, terraformOptions, keyPair, username, "../../build/zarf-init.tar.zst", fmt.Sprintf("/home/%s/build/zarf-init.tar.zst", username), "0600") - syncFileToRemoteServer(t, terraformOptions, keyPair, username, "../../build/zarf-package-appliance-demo-doom.tar.zst", fmt.Sprintf("/home/%s/build/zarf-package-appliance-demo-doom.tar.zst", username), "0600") - }) + syncFileToRemoteServer(t, terraformOptions, keyPair, username, "../../build/zarf", fmt.Sprintf("/home/%s/build/zarf", username), "0700") + syncFileToRemoteServer(t, terraformOptions, keyPair, username, "../../build/zarf-init.tar.zst", fmt.Sprintf("/home/%s/build/zarf-init.tar.zst", username), "0600") + syncFileToRemoteServer(t, terraformOptions, keyPair, username, "../../build/zarf-package-appliance-demo-doom.tar.zst", fmt.Sprintf("/home/%s/build/zarf-package-appliance-demo-doom.tar.zst", username), "0600") + }) - teststructure.RunTestStage(t, "TEST", func() { - terraformOptions := teststructure.LoadTerraformOptions(t, tmpFolder) - keyPair := teststructure.LoadEc2KeyPair(t, tmpFolder) + teststructure.RunTestStage(t, "TEST", func() { + terraformOptions := teststructure.LoadTerraformOptions(t, tmpFolder) + keyPair := teststructure.LoadEc2KeyPair(t, tmpFolder) - // Finally run the actual test - testGameExample(t, terraformOptions, keyPair,username) - }) + // Finally run the actual test + testGameExample(t, terraformOptions, keyPair, username) + }) } func testGameExample(t *testing.T, terraformOptions *terraform.Options, keyPair *aws.Ec2Keypair, username string) { - // Run `terraform output` to get the value of an output variable - publicInstanceIP := terraform.Output(t, terraformOptions, "public_instance_ip") - - // We're going to try to SSH to the instance IP, using the Key Pair we created earlier, and the user "ubuntu", - // as we know the Instance is running an Ubuntu AMI that has such a user - publicHost := ssh.Host{ - Hostname: publicInstanceIP, - SshKeyPair: keyPair.KeyPair, - SshUserName: username, - } - - // Make sure `zarf --help` doesn't error - output, err := ssh.CheckSshCommandE(t, publicHost, fmt.Sprintf("sudo /home/%s/build/zarf --help", username)) - require.NoError(t, err, output) - - // run `zarf init` - output, err = ssh.CheckSshCommandE(t, publicHost, fmt.Sprintf("sudo bash -c 'cd /home/%s/build && ./zarf init --confirm --components management --host localhost'", username)) - require.NoError(t, err, output) - - // Wait until the Docker registry is ready - output, err = ssh.CheckSshCommandE(t, publicHost, "timeout 300 bash -c 'while [[ \"$(curl -sfSL --retry 15 --retry-connrefused --retry-delay 5 -o /dev/null -w \"%{http_code}\" \"https://localhost/v2/\")\" != \"200\" ]]; do sleep 1; done' || false") - require.NoError(t, err, output) - - // Deploy the game - output, err = ssh.CheckSshCommandE(t, publicHost, fmt.Sprintf("sudo bash -c 'cd /home/%s/build && ./zarf package deploy zarf-package-appliance-demo-doom.tar.zst --confirm'", username)) - require.NoError(t, err, output) - - // Wait for the game to be live. Right now we're just checking that `curl` returns 0. It can be enhanced by scraping the HTML that gets returned or something. - output, err = ssh.CheckSshCommandE(t, publicHost, "timeout 300 bash -c 'while [[ \"$(curl -sfSL --retry 15 --retry-connrefused --retry-delay 5 -o /dev/null -w \"%{http_code}\" \"https://localhost\")\" != \"200\" ]]; do sleep 1; done' || false") - require.NoError(t, err, output) - - // Run `zarf destroy` to make sure that works correctly - output, err = ssh.CheckSshCommandE(t, publicHost, fmt.Sprintf("sudo bash -c 'cd /home/%s/build && ./zarf destroy --confirm'", username)) - require.NoError(t, err, output) + // Run `terraform output` to get the value of an output variable + publicInstanceIP := terraform.Output(t, terraformOptions, "public_instance_ip") + + // We're going to try to SSH to the instance IP, using the Key Pair we created earlier, and the user "ubuntu", + // as we know the Instance is running an Ubuntu AMI that has such a user + publicHost := ssh.Host{ + Hostname: publicInstanceIP, + SshKeyPair: keyPair.KeyPair, + SshUserName: username, + } + + // Make sure `zarf --help` doesn't error + output, err := ssh.CheckSshCommandE(t, publicHost, fmt.Sprintf("sudo /home/%s/build/zarf --help", username)) + require.NoError(t, err, output) + + // run `zarf init` + output, err = ssh.CheckSshCommandE(t, publicHost, fmt.Sprintf("sudo bash -c 'cd /home/%s/build && ./zarf init --confirm --components management --host localhost'", username)) + require.NoError(t, err, output) + + // Wait until the Docker registry is ready + output, err = ssh.CheckSshCommandE(t, publicHost, "timeout 300 bash -c 'while [[ \"$(curl -sfSL --retry 15 --retry-connrefused --retry-delay 5 -o /dev/null -w \"%{http_code}\" \"https://localhost/v2/\")\" != \"200\" ]]; do sleep 1; done' || false") + require.NoError(t, err, output) + + // Deploy the game + output, err = ssh.CheckSshCommandE(t, publicHost, fmt.Sprintf("sudo bash -c 'cd /home/%s/build && ./zarf package deploy zarf-package-appliance-demo-doom.tar.zst --confirm'", username)) + require.NoError(t, err, output) + + // Wait for the game to be live. Right now we're just checking that `curl` returns 0. It can be enhanced by scraping the HTML that gets returned or something. + output, err = ssh.CheckSshCommandE(t, publicHost, "timeout 300 bash -c 'while [[ \"$(curl -sfSL --retry 15 --retry-connrefused --retry-delay 5 -o /dev/null -w \"%{http_code}\" \"https://localhost\")\" != \"200\" ]]; do sleep 1; done' || false") + require.NoError(t, err, output) + + // Run `zarf destroy` to make sure that works correctly + output, err = ssh.CheckSshCommandE(t, publicHost, fmt.Sprintf("sudo bash -c 'cd /home/%s/build && ./zarf destroy --confirm'", username)) + require.NoError(t, err, output) } diff --git a/test/e2e/e2e_general_cli_test.go b/test/e2e/e2e_general_cli_test.go index 6834cb144e..17f8773500 100644 --- a/test/e2e/e2e_general_cli_test.go +++ b/test/e2e/e2e_general_cli_test.go @@ -1,94 +1,94 @@ package test import ( - "fmt" - "github.com/gruntwork-io/terratest/modules/aws" - "github.com/gruntwork-io/terratest/modules/ssh" - "github.com/gruntwork-io/terratest/modules/terraform" - teststructure "github.com/gruntwork-io/terratest/modules/test-structure" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "testing" + "fmt" + "github.com/gruntwork-io/terratest/modules/aws" + "github.com/gruntwork-io/terratest/modules/ssh" + "github.com/gruntwork-io/terratest/modules/terraform" + teststructure "github.com/gruntwork-io/terratest/modules/test-structure" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "testing" ) func TestGeneralCli(t *testing.T) { - t.Parallel() + t.Parallel() - // Our SSH username, will change based on which AMI we use - username := "ubuntu" + // Our SSH username, will change based on which AMI we use + username := "ubuntu" - // Copy the terraform folder to a temp directory so we can run multiple tests in parallel - tmpFolder := teststructure.CopyTerraformFolderToTemp(t, "..", "tf/public-ec2-instance") + // Copy the terraform folder to a temp directory so we can run multiple tests in parallel + tmpFolder := teststructure.CopyTerraformFolderToTemp(t, "..", "tf/public-ec2-instance") - // At the end of the test, run `terraform destroy` to clean up any resources that were created - defer teststructure.RunTestStage(t, "TEARDOWN", func() { - teardown(t, tmpFolder) - }) + // At the end of the test, run `terraform destroy` to clean up any resources that were created + defer teststructure.RunTestStage(t, "TEARDOWN", func() { + teardown(t, tmpFolder) + }) - // Deploy the terraform infra - teststructure.RunTestStage(t, "SETUP", func() { - setup(t, tmpFolder) - }) + // Deploy the terraform infra + teststructure.RunTestStage(t, "SETUP", func() { + setup(t, tmpFolder) + }) - // Upload the Zarf artifacts - teststructure.RunTestStage(t, "UPLOAD", func() { - terraformOptions := teststructure.LoadTerraformOptions(t, tmpFolder) - keyPair := teststructure.LoadEc2KeyPair(t, tmpFolder) + // Upload the Zarf artifacts + teststructure.RunTestStage(t, "UPLOAD", func() { + terraformOptions := teststructure.LoadTerraformOptions(t, tmpFolder) + keyPair := teststructure.LoadEc2KeyPair(t, tmpFolder) - syncFileToRemoteServer(t, terraformOptions, keyPair, username, "../../build/zarf", fmt.Sprintf("/home/%s/build/zarf", username), "0700") - }) + syncFileToRemoteServer(t, terraformOptions, keyPair, username, "../../build/zarf", fmt.Sprintf("/home/%s/build/zarf", username), "0700") + }) - teststructure.RunTestStage(t, "TEST", func() { - terraformOptions := teststructure.LoadTerraformOptions(t, tmpFolder) - keyPair := teststructure.LoadEc2KeyPair(t, tmpFolder) + teststructure.RunTestStage(t, "TEST", func() { + terraformOptions := teststructure.LoadTerraformOptions(t, tmpFolder) + keyPair := teststructure.LoadEc2KeyPair(t, tmpFolder) - // Finally run the actual test - testGeneralCliStuff(t, terraformOptions, keyPair,username) - }) + // Finally run the actual test + testGeneralCliStuff(t, terraformOptions, keyPair, username) + }) } func testGeneralCliStuff(t *testing.T, terraformOptions *terraform.Options, keyPair *aws.Ec2Keypair, username string) { - // Run `terraform output` to get the value of an output variable - publicInstanceIP := terraform.Output(t, terraformOptions, "public_instance_ip") - - // We're going to try to SSH to the instance IP, using the Key Pair we created earlier, and the user "ubuntu", - // as we know the Instance is running an Ubuntu AMI that has such a user - publicHost := ssh.Host{ - Hostname: publicInstanceIP, - SshKeyPair: keyPair.KeyPair, - SshUserName: username, - } - - // Test `zarf prepare sha256sum` for a local asset - expectedShasum := "61b50898f982d015ed87093ba822de0fe011cec6dd67db39f99d8c56391a6109\n" - output,err := ssh.CheckSshCommandE(t, publicHost, fmt.Sprintf("cd /home/%s/build && echo 'random test data 🦄' > shasum-test-file", username)) - require.NoError(t, err, output) - output,err = ssh.CheckSshCommandE(t, publicHost, fmt.Sprintf("cd /home/%s/build && ./zarf prepare sha256sum shasum-test-file 2> /dev/null", username)) - require.NoError(t, err, output) - assert.Equal(t, expectedShasum, output, "The expected SHASUM should equal the actual SHASUM") - - // Test `zarf prepare sha256sum` for a remote asset - expectedShasum = "c3cdea0573ba5a058ec090b5d2683bf398e8b1614c37ec81136ed03b78167617\n" - output,err = ssh.CheckSshCommandE(t, publicHost, fmt.Sprintf("cd /home/%s/build && ./zarf prepare sha256sum https://zarf-public.s3-us-gov-west-1.amazonaws.com/pipelines/zarf-prepare-shasum-remote-test-file.txt 2> /dev/null", username)) - require.NoError(t, err, output) - assert.Equal(t, expectedShasum, output, "The expected SHASUM should equal the actual SHASUM") - - // Test `zarf version` - output, err = ssh.CheckSshCommandE(t, publicHost, fmt.Sprintf("cd /home/%s/build && ./zarf version", username)) - require.NoError(t, err, output) - assert.NotNil(t, output) - assert.NotEqual(t, len(output), 0, "Zarf version should not be an empty string") - assert.NotEqual(t, string(output), "UnknownVersion", "Zarf version should not be the default value") - - // Test for expected failure when given a bad component input - output, err = ssh.CheckSshCommandE(t, publicHost, fmt.Sprintf("cd /home/%s/build && ./zarf init --components management,foo,logging", username)) - require.Error(t, err, output) - - // Test for expected failure when given invalid hostnames - output, err = ssh.CheckSshCommandE(t, publicHost, fmt.Sprintf("cd /home/%s/build && ./zarf init --host bad!hostname", username)) - require.Error(t, err, output) - output, err = ssh.CheckSshCommandE(t, publicHost, fmt.Sprintf("cd /home/%s/build && ./zarf pki regenerate --host zarf@server", username)) - require.Error(t, err, output) - output, err = ssh.CheckSshCommandE(t, publicHost, fmt.Sprintf("cd /home/%s/build && ./zarf pki regenerate --host some_unique_server", username)) - require.Error(t, err, output) + // Run `terraform output` to get the value of an output variable + publicInstanceIP := terraform.Output(t, terraformOptions, "public_instance_ip") + + // We're going to try to SSH to the instance IP, using the Key Pair we created earlier, and the user "ubuntu", + // as we know the Instance is running an Ubuntu AMI that has such a user + publicHost := ssh.Host{ + Hostname: publicInstanceIP, + SshKeyPair: keyPair.KeyPair, + SshUserName: username, + } + + // Test `zarf prepare sha256sum` for a local asset + expectedShasum := "61b50898f982d015ed87093ba822de0fe011cec6dd67db39f99d8c56391a6109\n" + output, err := ssh.CheckSshCommandE(t, publicHost, fmt.Sprintf("cd /home/%s/build && echo 'random test data 🦄' > shasum-test-file", username)) + require.NoError(t, err, output) + output, err = ssh.CheckSshCommandE(t, publicHost, fmt.Sprintf("cd /home/%s/build && ./zarf prepare sha256sum shasum-test-file 2> /dev/null", username)) + require.NoError(t, err, output) + assert.Equal(t, expectedShasum, output, "The expected SHASUM should equal the actual SHASUM") + + // Test `zarf prepare sha256sum` for a remote asset + expectedShasum = "c3cdea0573ba5a058ec090b5d2683bf398e8b1614c37ec81136ed03b78167617\n" + output, err = ssh.CheckSshCommandE(t, publicHost, fmt.Sprintf("cd /home/%s/build && ./zarf prepare sha256sum https://zarf-public.s3-us-gov-west-1.amazonaws.com/pipelines/zarf-prepare-shasum-remote-test-file.txt 2> /dev/null", username)) + require.NoError(t, err, output) + assert.Equal(t, expectedShasum, output, "The expected SHASUM should equal the actual SHASUM") + + // Test `zarf version` + output, err = ssh.CheckSshCommandE(t, publicHost, fmt.Sprintf("cd /home/%s/build && ./zarf version", username)) + require.NoError(t, err, output) + assert.NotNil(t, output) + assert.NotEqual(t, len(output), 0, "Zarf version should not be an empty string") + assert.NotEqual(t, string(output), "UnknownVersion", "Zarf version should not be the default value") + + // Test for expected failure when given a bad component input + output, err = ssh.CheckSshCommandE(t, publicHost, fmt.Sprintf("cd /home/%s/build && ./zarf init --components management,foo,logging", username)) + require.Error(t, err, output) + + // Test for expected failure when given invalid hostnames + output, err = ssh.CheckSshCommandE(t, publicHost, fmt.Sprintf("cd /home/%s/build && ./zarf init --host bad!hostname", username)) + require.Error(t, err, output) + output, err = ssh.CheckSshCommandE(t, publicHost, fmt.Sprintf("cd /home/%s/build && ./zarf pki regenerate --host zarf@server", username)) + require.Error(t, err, output) + output, err = ssh.CheckSshCommandE(t, publicHost, fmt.Sprintf("cd /home/%s/build && ./zarf pki regenerate --host some_unique_server", username)) + require.Error(t, err, output) }