From 0d1cf479ac983fc35b84cb29959f80aec303928d Mon Sep 17 00:00:00 2001 From: Ori Hoch Date: Tue, 19 May 2020 18:13:18 +0300 Subject: [PATCH] end to end test + CI --- .github/workflows/main.yml | 100 +++++++++++++++++++++ .gitignore | 4 + common.go | 2 +- resource_server.go | 4 +- tests/e2e_test.py | 173 +++++++++++++++++++++++++++++++++++++ tests/main.tf | 4 +- 6 files changed, 282 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/main.yml create mode 100644 tests/e2e_test.py diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..fe5ed1c --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,100 @@ +name: CI +on: + push: +jobs: + build: + runs-on: ubuntu-18.04 + steps: + - uses: actions/checkout@v2 + - run: | + if [[ $GITHUB_REF == refs/tags/* ]]; then + VERSION="$(echo $GITHUB_REF | sed -e 's:refs/tags/::')" + else + VERSION=0.0.0 + fi &&\ + mkdir -p build &&\ + gobuild() { + echo building "${1} ${2}..." &&\ + if [ "${1}" == "windows" ]; then + EXT=".exe" + else + EXT="" + fi &&\ + GOOS=$1 GOARCH=$2 go build -ldflags "-X main.Version=${VERSION}" -o "build/terraform-provider-kamatera-${VERSION}-${1}-${2}${EXT}" &&\ + pushd build &&\ + zip "terraform-provider-kamatera-${VERSION}-${1}-${2}.zip" "terraform-provider-kamatera-${VERSION}-${1}-${2}${EXT}" &&\ + rm -f "terraform-provider-kamatera-${VERSION}-${1}-${2}${EXT}" &&\ + popd + } &&\ + gobuild darwin amd64 &&\ + gobuild freebsd 386 &&\ + gobuild freebsd amd64 &&\ + gobuild freebsd arm &&\ + gobuild linux 386 &&\ + gobuild linux amd64 &&\ + gobuild linux arm &&\ + gobuild openbsd 386 &&\ + gobuild openbsd amd64 &&\ + gobuild solaris amd64 &&\ + gobuild windows 386 &&\ + gobuild windows amd64 + - uses: actions/upload-artifact@v1 + if: always() + with: + name: build + path: build + test: + runs-on: ubuntu-18.04 + steps: + - uses: actions/checkout@v2 + - env: + KAMATERA_API_CLIENT_ID: ${{ secrets.KAMATERA_API_CLIENT_ID }} + KAMATERA_API_SECRET: ${{ secrets.KAMATERA_API_SECRET }} + run: | + if [[ $GITHUB_REF == refs/tags/* ]]; then + VERSION="$(echo $GITHUB_REF | sed -e 's:refs/tags/::')" + else + VERSION=0.0.0 + fi &&\ + go build -ldflags "-X main.Version=${VERSION}" -o terraform-provider-kamatera &&\ + curl -sSL https://releases.hashicorp.com/terraform/0.12.25/terraform_0.12.25_linux_amd64.zip -o terraform.zip &&\ + unzip terraform.zip &&\ + curl -sSL https://cloudcli.cloudwm.com/binaries/latest/cloudcli-linux-amd64.tar.gz -o cloudcli.tar.gz &&\ + tar -xzvf cloudcli.tar.gz &&\ + chmod +x terraform-provider-kamatera terraform cloudcli &&\ + export PATH=`pwd`:$PATH &&\ + python3 tests/e2e_test.py + - uses: actions/upload-artifact@v1 + if: always() + with: + name: tests_output + path: tests/output + publish: + runs-on: ubuntu-18.04 + needs: + - build + - test + steps: + - uses: actions/download-artifact@v1 + with: + name: build + - env: + KAMATERA_MACHINE_USER_TOKEN: ${{ secrets.KAMATERA_MACHINE_USER_TOKEN }} + run: | + if [[ $GITHUB_REF == refs/tags/* ]]; then + VERSION="$(echo $GITHUB_REF | sed -e 's:refs/tags/::')" &&\ + RELEASE_ID="$(curl -sL https://api.github.com/repos/Kamatera/terraform-provider-kamatera/releases/tags/${VERSION} | jq -r .id)" &&\ + echo uploading binaries to release RELEASE_ID=$RELEASE_ID &&\ + cd build &&\ + for FILE in `ls *.zip`; do + if [ "$(curl -H "Authorization: token $KAMATERA_MACHINE_USER_TOKEN" \ + -H "Content-Type: $(file -b --mime-type $FILE)" \ + --data-binary @$FILE \ + "https://uploads.github.com/repos/Kamatera/terraform-provider-kamatera/releases/${RELEASE_ID}/assets?name=$(basename $FILE)" | tee /dev/stderr | jq -r .state)" == "uploaded" ]; then + echo Release asset $FILE uploaded successfuly + else + echo Failed to upload release asset $FILE + exit 1 + fi + done + fi diff --git a/.gitignore b/.gitignore index ad4aa3f..a95781b 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,7 @@ terraform-provider-kamatera terraform.tfstate* .idea crash.log +tests/output +build +cloudcli* +terraform diff --git a/common.go b/common.go index 1ed757b..0da74ba 100644 --- a/common.go +++ b/common.go @@ -52,7 +52,7 @@ func waitCommand(provider ProviderConfiguration, commandId string) (map[string]i startTime := time.Now() time.Sleep(2 * time.Second) for { - if startTime.Add(600 * time.Second).Sub(time.Now()) < 0 { + if startTime.Add(2400 * time.Second).Sub(time.Now()) < 0 { return nil, errors.New("timeout waiting for Kamatera command to complete") } time.Sleep(2 * time.Second) diff --git a/resource_server.go b/resource_server.go index 5f9163e..b1a9a26 100644 --- a/resource_server.go +++ b/resource_server.go @@ -110,12 +110,12 @@ func resourceServer() *schema.Resource { }, "public_ips": &schema.Schema{ Type: schema.TypeList, - Elem: schema.TypeString, + Elem: &schema.Schema{Type: schema.TypeString,}, Computed: true, }, "private_ips": &schema.Schema{ Type: schema.TypeList, - Elem: schema.TypeString, + Elem: &schema.Schema{Type: schema.TypeString,}, Computed: true, }, }, diff --git a/tests/e2e_test.py b/tests/e2e_test.py new file mode 100644 index 0000000..6b65f3a --- /dev/null +++ b/tests/e2e_test.py @@ -0,0 +1,173 @@ +#!/usr/bin/env python3 +import os +import subprocess +import json + + +os.makedirs("tests/output", exist_ok=True) +CREATE_SERVER_NAME = "terraformtest" + +CLOUDCLI_ARGS = ["--api-clientid", os.environ["KAMATERA_API_CLIENT_ID"], "--api-secret", os.environ["KAMATERA_API_SECRET"]] + + +def test_create_server(): + with open("tests/output/main.tf", "w") as f: + f.write(""" + provider "kamatera" {} + + data "kamatera_datacenter" "petach_tikva" { + country = "Israel" + name = "Petach Tikva" + } + + data "kamatera_image" "ubuntu_1804" { + datacenter_id = data.kamatera_datacenter.petach_tikva.id + os = "Ubuntu" + code = "18.04 64bit" + } + + data "kamatera_server_options" "B2_2048_monthly" { + datacenter_id = data.kamatera_datacenter.petach_tikva.id + cpu_type = "B" + cpu_cores = 2 + ram_mb = 2048 + disk_size_gb = 15 + extra_disk_sizes_gb = [20, 30] + billing_cycle = "monthly" + } + + resource "kamatera_server" "__CREATE_SERVER_NAME__" { + name = "__CREATE_SERVER_NAME__" + server_options_id = data.kamatera_server_options.B2_2048_monthly.id + image_id = data.kamatera_image.ubuntu_1804.id + } + """.replace("__CREATE_SERVER_NAME__", CREATE_SERVER_NAME)) + if os.path.exists("terraform.tfstate") or os.path.exists("terraform.tfstate.backup"): + raise Exception("Existing terraform state") + subprocess.check_call(["terraform", "init", "tests/output"]) + print("Creating server...") + subprocess.check_call(["terraform", "apply", "-auto-approve", "-input=false", "tests/output"]) + with open("tests/output/test_create.json", "wb") as f: + f.write(subprocess.check_output(["cloudcli", *CLOUDCLI_ARGS, "server", "info", "--format", "json", "--name", "%s.*" % CREATE_SERVER_NAME])) + with open("tests/output/test_create.json", "rb") as f: + servers_info = json.load(f) + assert len(servers_info) == 1 + server = servers_info[0] + assert len(server["id"]) > 5 + assert server["datacenter"] == "IL-PT" + assert server["cpu"] == "2B" + assert server["name"].startswith(CREATE_SERVER_NAME) + assert server["ram"] == 2048 + assert server["power"] == "on" + assert server["diskSizes"] == [15, 20, 30] + assert server["networks"][0]["network"] == "wan-il-pt" + assert server["billing"] == "monthly" + assert server["traffic"] == "t5000" + assert server["managed"] == "0" + assert server["backup"] == "0" + + +def test_stop_server(): + with open("tests/output/main.tf", "w") as f: + f.write(""" + provider "kamatera" {} + + data "kamatera_datacenter" "petach_tikva" { + country = "Israel" + name = "Petach Tikva" + } + + data "kamatera_image" "ubuntu_1804" { + datacenter_id = data.kamatera_datacenter.petach_tikva.id + os = "Ubuntu" + code = "18.04 64bit" + } + + data "kamatera_server_options" "B2_2048_monthly" { + datacenter_id = data.kamatera_datacenter.petach_tikva.id + cpu_type = "B" + cpu_cores = 2 + ram_mb = 2048 + disk_size_gb = 15 + extra_disk_sizes_gb = [20, 30] + billing_cycle = "monthly" + } + + resource "kamatera_server" "__CREATE_SERVER_NAME__" { + name = "__CREATE_SERVER_NAME__" + server_options_id = data.kamatera_server_options.B2_2048_monthly.id + image_id = data.kamatera_image.ubuntu_1804.id + power_on = false + } + """.replace("__CREATE_SERVER_NAME__", CREATE_SERVER_NAME)) + print("Stopping server...") + subprocess.check_call(["terraform", "apply", "-auto-approve", "-input=false", "tests/output"]) + with open("tests/output/test_stop.json", "wb") as f: + f.write(subprocess.check_output(["cloudcli", *CLOUDCLI_ARGS, "server", "info", "--format", "json", "--name", "%s.*" % CREATE_SERVER_NAME])) + with open("tests/output/test_stop.json", "rb") as f: + servers_info = json.load(f) + assert len(servers_info) == 1 + server = servers_info[0] + assert server["name"].startswith(CREATE_SERVER_NAME) + assert server["power"] == "off" + + +def test_change_server_options(): + with open("tests/output/main.tf", "w") as f: + f.write(""" + provider "kamatera" {} + + data "kamatera_datacenter" "petach_tikva" { + country = "Israel" + name = "Petach Tikva" + } + + data "kamatera_image" "ubuntu_1804" { + datacenter_id = data.kamatera_datacenter.petach_tikva.id + os = "Ubuntu" + code = "18.04 64bit" + } + + data "kamatera_server_options" "B1_1024_monthly" { + datacenter_id = data.kamatera_datacenter.petach_tikva.id + cpu_type = "B" + cpu_cores = 1 + ram_mb = 1024 + disk_size_gb = 15 + extra_disk_sizes_gb = [20, 30] + billing_cycle = "monthly" + } + + resource "kamatera_server" "__CREATE_SERVER_NAME__" { + name = "__CREATE_SERVER_NAME__" + server_options_id = data.kamatera_server_options.B1_1024_monthly.id + image_id = data.kamatera_image.ubuntu_1804.id + power_on = false + } + """.replace("__CREATE_SERVER_NAME__", CREATE_SERVER_NAME)) + print("Changing server options...") + subprocess.check_call(["terraform", "apply", "-auto-approve", "-input=false", "tests/output"]) + with open("tests/output/test_change_options.json", "wb") as f: + f.write(subprocess.check_output(["cloudcli", *CLOUDCLI_ARGS, "server", "info", "--format", "json", "--name", "%s.*" % CREATE_SERVER_NAME])) + with open("tests/output/test_change_options.json", "rb") as f: + servers_info = json.load(f) + assert len(servers_info) == 1 + server = servers_info[0] + assert server["cpu"] == "1B" + assert server["name"].startswith(CREATE_SERVER_NAME) + assert server["ram"] == 1024 + + +def test_destroy_server(): + print("Destroying server...") + subprocess.check_call(["terraform", "destroy", "-auto-approve", "tests/output"]) + status, output = subprocess.getstatusoutput("cloudcli %s server info --format json --name \"%s.*\"" % (" ".join(CLOUDCLI_ARGS), CREATE_SERVER_NAME)) + assert status == 2, output + assert "No servers found" in output, output + + +test_create_server() +test_stop_server() +test_change_server_options() +test_destroy_server() +print("Great Success!") diff --git a/tests/main.tf b/tests/main.tf index e95f1f5..31d75e4 100644 --- a/tests/main.tf +++ b/tests/main.tf @@ -21,8 +21,8 @@ data "kamatera_server_options" "B2_2048_monthly" { billing_cycle = "monthly" } -resource "kamatera_server" "my-server3" { - name = "my-server5" +resource "kamatera_server" "terraformtest" { + name = "terraformtest" server_options_id = data.kamatera_server_options.B2_2048_monthly.id image_id = data.kamatera_image.ubuntu_1804.id }