Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add windows to integration tests #45

Merged
merged 36 commits into from
Jul 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
26b8abd
test windows
obs-gh-nikhildua Jul 1, 2024
adc45f1
remove string 386
obs-gh-nikhildua Jul 1, 2024
80119af
revert
obs-gh-nikhildua Jul 1, 2024
07f7ad5
updates for windows scripts
obs-gh-nikhildua Jul 1, 2024
821090c
add placeholders for windows scripts
obs-gh-nikhildua Jul 1, 2024
d775496
reduce parallelism
obs-gh-nikhildua Jul 1, 2024
62b5a19
Merge branch 'main' into nikhil/integration-testing-windows
obs-gh-nikhildua Jul 1, 2024
e05d51d
ec2 connection for windows
obs-gh-nikhildua Jul 2, 2024
719d369
trying out installation
obs-gh-nikhildua Jul 3, 2024
5529be9
try windows
obs-gh-nikhildua Jul 3, 2024
6aee1e9
update error handling
obs-gh-nikhildua Jul 3, 2024
63cc297
update install script
obs-gh-nikhildua Jul 3, 2024
4b4314e
remove wait time
obs-gh-nikhildua Jul 3, 2024
75aa8a6
fix tf version for consis
obs-gh-nikhildua Jul 3, 2024
ce0f9c4
don't try merge commit
obs-gh-nikhildua Jul 3, 2024
a0e25a0
revert push limit
obs-gh-nikhildua Jul 3, 2024
ed752cc
comment
obs-gh-nikhildua Jul 3, 2024
ab3ac37
Merge branch 'main' into nikhil/integration-testing-windows
obs-gh-nikhildua Jul 3, 2024
0a85817
update install script to just install only
obs-gh-nikhildua Jul 3, 2024
b7dda91
rename
obs-gh-nikhildua Jul 3, 2024
558c46a
update comments
obs-gh-nikhildua Jul 8, 2024
067b25d
try test version
obs-gh-nikhildua Jul 8, 2024
630bd4e
try diagnose
obs-gh-nikhildua Jul 8, 2024
da7ebc3
try script for status
obs-gh-nikhildua Jul 10, 2024
180e370
add windows 2019
obs-gh-nikhildua Jul 15, 2024
826dca0
addnl comments
obs-gh-nikhildua Jul 15, 2024
ffcecb0
set pw to sensitive
obs-gh-nikhildua Jul 15, 2024
7737339
RM & utils update for mask
obs-gh-nikhildua Jul 15, 2024
c777915
fix utils typo
obs-gh-nikhildua Jul 15, 2024
efe7015
support None pw
obs-gh-nikhildua Jul 15, 2024
30cd10c
update mask func
obs-gh-nikhildua Jul 15, 2024
10a1728
fix None
obs-gh-nikhildua Jul 15, 2024
6e942a5
Add Windows 2022
obs-gh-nikhildua Jul 15, 2024
738bb94
fix w2022 ami
obs-gh-nikhildua Jul 15, 2024
75378be
update ec2 user script test
obs-gh-nikhildua Jul 15, 2024
3ae7c9f
Addnl comments
obs-gh-nikhildua Jul 15, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .github/workflows/tests-integration.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,7 @@ jobs:
strategy:
fail-fast: false
matrix:
#AWS_MACHINE: ["AMAZON_LINUX_2023", "RHEL_8_4_0"]
AWS_MACHINE: ["AMAZON_LINUX_2023", "UBUNTU_22_04_LTS"]
AWS_MACHINE: ["AMAZON_LINUX_2023", "UBUNTU_22_04_LTS", "WINDOWS_SERVER_2016_BASE", "WINDOWS_SERVER_2019_BASE", "WINDOWS_SERVER_2022_BASE"]
defaults:
run:
working-directory: integration #Terrafrom commands and tests are ran from integration directory
Expand Down Expand Up @@ -101,6 +100,8 @@ jobs:

- name: Setup Terraform
uses: hashicorp/setup-terraform@v3
with:
terraform_version: 1.8.5

- name: Terraform Init
id: init
Expand Down
23 changes: 22 additions & 1 deletion integration/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ or through a `provider_override.tf` placed in `modules/create_ec2` directory.

### Local Testing

Any of the python scripts in the `/scripts` directory can be tested by running them directly, granted an EC2 Machine exists. As the scripts rely on the outputs of `create_ec2` and `setup_observe_variables` modules to be passed in as environment variables, these environment variables can be manually set if the modules are not ran.
Any of the python scripts in the `/scripts` directory can be tested by running them directly, granted an EC2 Machine exists. As the scripts rely on the outputs of `create_ec2` and `setup_observe_variables` modules to be passed in as environment variables, these environment variables can be manually set if the set up modules are not ran.

The `/scripts/<test_xyz.py` expects the following environment variables to be set:

Expand All @@ -62,8 +62,29 @@ MACHINE_NAME="UBUNTU_22_04_LTS" #Machine name to test
MACHINE_CONFIG="ami_description:Ubuntu Server 22.04 LTS (HVM)- EBS General Purpose (SSD) Volume Type. Support available from Canonical,ami_id:ami-036cafe742923b3d9,ami_instance_type:t3.small,architecture:amd64,default_user:ubuntu,distribution:debian,package_type:.deb,sleep:120,user_data:user_data/aptbased.sh" #Machine config
OBSERVE_URL="" #Observe URL to use for testing
OBSERVE_TOKEN="" #Observe Token to use for testing
PASSWORD="WindowsPassword to be used for testing" # Set to None for testing

```

Run the scripts from the folder as below:
```
➜ integration git:(nikhil/integration-testing-windows) ✗ pwd
/Users/nikhil.dua/Documents/observe-repos/observe-agent/integration
➜ integration git:(nikhil/integration-testing-windows) ✗ python3 scripts/test_installation.py
```

Note: If testing Windows machines, the RDP password is redacted by default in the python scripts.
This can be turned off when disabling mask by setting below environment variable to `False` before running these scripts
```
export MASK=False
python3 scripts/test_ec2_connection.py
------------------------------
Masking Disabled
Env vars set to:
{'host': '54.177.26.178', 'user': 'Administrator', 'key_filename': './test_key.pem', 'password': '<exposed_password>, 'machine_name': 'WINDOWS_SERVER_2016_BASE', 'machine_config': {'ami_description': 'Microsoft Windows Server 2016 with Desktop Experience Locale English AMI provided by Amazon', 'ami_id': 'ami-07357c8c8d7501f94', 'ami_instance_type': 't3.small', 'architecture': 'x86_64', 'default_user': 'Administrator', 'distribution': 'windows', 'package_type': '.zip', 'sleep': '120', 'user_data': 'user_data/windows.ps'}, 'observe_url': 'https://179969258044.collect.observe-staging.com/', 'observe_token': '<exposed_token>}
------------------------------
Testing SSH connection to host 54.177.26.178 with timeout 120s
```

### Architecture

Expand Down
59 changes: 35 additions & 24 deletions integration/modules/create_ec2/locals.tf
Original file line number Diff line number Diff line change
Expand Up @@ -74,34 +74,45 @@ locals {
# user_data = "user_data/yumbased.sh"
# }

# WINDOWS_SERVER_2016_BASE = {
# ami_instance_type = "t3.small"
# ami_id = "ami-0e87182c1094f2344"
# ami_description = "Microsoft Windows Server 2016 with Desktop Experience Locale English AMI provided by Amazon"
# default_user = "Administrator"
# sleep = 120
# user_data = "user_data/windows.ps"
# }
WINDOWS_SERVER_2016_BASE = {
ami_instance_type = "t3.small"
ami_id = "ami-07357c8c8d7501f94"
ami_description = "Microsoft Windows Server 2016 with Desktop Experience Locale English AMI provided by Amazon"
default_user = "Administrator"
sleep = 120
user_data = "user_data/windows.ps"
distribution = "windows"
package_type = ".zip"
architecture = "x86_64"
}

# WINDOWS_SERVER_2019_BASE = {
# ami_instance_type = "t3.small"
# ami_id = "ami-01dc5695dfebe46cc"
# ami_description = "Microsoft Windows Server 2019 with Desktop Experience Locale English AMI provided by Amazon"
# default_user = "Administrator"
# sleep = 120
# user_data = "user_data/windows.ps"
# }

# WINDOWS_SERVER_2022_BASE = {
# ami_instance_type = "t3.small"
# ami_id = "ami-091f300417a06d788"
# ami_description = "Microsoft Windows Server 2022 Full Locale English AMI provided by Amazon"
# default_user = "Administrator"
# sleep = 120
# user_data = "user_data/windows.ps"
# }
WINDOWS_SERVER_2019_BASE = {
ami_instance_type = "t3.small"
ami_id = "ami-006bce2026b3f63b8"
ami_description = "Microsoft Windows Server 2019 with Desktop Experience Locale English AMI provided by Amazon"
default_user = "Administrator"
sleep = 120
user_data = "user_data/windows.ps"
distribution = "windows"
package_type = ".zip"
architecture = "x86_64"
}


WINDOWS_SERVER_2022_BASE = {
ami_instance_type = "t3.small"
ami_id = "ami-0fdf7c7a70369b831"
ami_description = "Microsoft Windows Server 2022 Full Locale English AMI provided by Amazon"
default_user = "Administrator"
sleep = 120
user_data = "user_data/windows.ps"
distribution = "windows"
package_type = ".zip"
architecture = "x86_64"
}


}
}

Expand Down
5 changes: 4 additions & 1 deletion integration/modules/create_ec2/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ output "private_key_path" {

output "public_ssh_link" {
value = "ssh -i ${var.PRIVATE_KEY_PATH} ${local.AWS_MACHINE_CONFIGS[var.AWS_MACHINE].default_user}@${aws_instance.observe_agent_instance.public_ip}"

}

output "password" {
value = can(regex("WINDOWS", var.AWS_MACHINE)) ? rsadecrypt(aws_instance.observe_agent_instance.password_data, file(var.PRIVATE_KEY_PATH)) : "None"
sensitive = true
}
Binary file not shown.
42 changes: 42 additions & 0 deletions integration/scripts/install_windows.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# This scripts take an $local_install parameter, unzips the observe-agent .zip file and
# and copies the relevant files to C:\Program Files\Observe\observe-agent
# It's intended to only install observe-agent on a windows machine and ensure no issues take place

#$local_installer="C:\Users\Administrator\observe-agent_Windows_x86_64.zip" This is set from python

param (
[Parameter(Mandatory=$true)]
[string]$local_installer
)
#Parameter is local_installer .zip file (which should already exist on machine)
Write-Output "Local installer path is located at: $local_installer"

$program_data_filestorage="C:\ProgramData\Observe\observe-agent\filestorage"
$observeagent_install_dir="$env:ProgramFiles\Observe\observe-agent"
$temp_dir="C:\temp"

#Create directories for temp & observe-agent installation ls
New-Item -ItemType Directory -Force -Path $temp_dir
New-Item -ItemType Directory -Force -Path $observeagent_install_dir
New-Item -ItemType Directory -Force -Path $observeagent_install_dir\config
New-Item -ItemType Directory -Force -Path $program_data_filestorage

# Stop the observe agent if its running so that we can copy the new .exe
if((Get-Service ObserveAgent -ErrorAction SilentlyContinue)){
obs-gh-nikhildua marked this conversation as resolved.
Show resolved Hide resolved
Write-Output "Observe Agent is running, Stopping Observe Agent..."
Stop-Service ObserveAgent
}

# Unzip the installer .zip to C:\temp\observe-agent_extract
# Eg: Unzip C:\Users\Administrator\observe-agent_Windows_x86_64.zip to C:\temp\observe-agent_extract
Write-Output "Unzipping installer $local_installer to $temp_dir\observe-agent_extract"
Expand-Archive -Force -LiteralPath $local_installer -DestinationPath "$temp_dir\observe-agent_extract"

# Copy relevant files from C:\temp\observe-agent_extract to C:\Program Files\Observe\observe-agent
Write-Output "Copying files from $temp_dir\observe-agent_extract to $observeagent_install_dir"
Copy-Item -Force -Path $temp_dir\observe-agent_extract\observe-agent.exe -Destination $observeagent_install_dir
Copy-Item -Force -Path $temp_dir\observe-agent_extract\observe-agent.yaml -Destination $observeagent_install_dir
Copy-Item -Force -Path $temp_dir\observe-agent_extract\otel-collector.yaml -Destination $observeagent_install_dir\config\otel-collector.yaml
Copy-Item -Force -Path $temp_dir\observe-agent_extract\connections\ -Destination $observeagent_install_dir\connections -Recurse


36 changes: 36 additions & 0 deletions integration/scripts/start_agent_windows.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
##This script is responsible for creating & starting the observe agent service

$observeagent_install_dir="$env:ProgramFiles\Observe\observe-agent"

if(-not (Get-Service ObserveAgent -ErrorAction SilentlyContinue)){
Write-Output "Creating ObserveAgent Service...."
$params = @{
Name = "ObserveAgent"
BinaryPathName = "`"${observeagent_install_dir}\observe-agent.exe`" `"${observeagent_install_dir}\observe-agent.yaml`""
DisplayName = "Observe Agent"
StartupType = "Automatic"
Description = "Observe Agent based on OpenTelemetry collector"
}

New-Service @params
Write-Output "Starting ObserveAgent Service..."
Start-Service ObserveAgent
}
else{
Write-Output "ObserveAgent Service already exists, restarting service..."
Stop-Service ObserveAgent
Start-Service ObserveAgent
}

## Placeholder below for future use
## Delete ObserveAgent service if needed

# if (Get-Service "ObserveAgent" -ErrorAction 'SilentlyContinue')
# {
# $service = Get-WmiObject -Class Win32_Service -Filter "Name='ObserveAgent'"
# $service.delete()
# Write-Host "ObserveAgent service deleted"
# }
# else{
# write-host "No service found."
# }
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,39 @@
import time
from utils import *

@print_test_decorator
def run_test_windows(remote_host: Host, env_vars: dict) -> None:

"""
Test to validate connection of observe-agent to Observe

Args:
remote_host (Host): instance to ssh into
env_vars (dict): environment variables passed into for testing

Raises:
ValueError: Something failed with initial config or observe-agent -> observe connection
"""

init_command='Set-Location "C:\Program Files\Observe\observe-agent"; ./observe-agent init-config --token {} --observe_url {}'.format(env_vars["observe_token"], env_vars["observe_url"])
diagnose_command='Set-Location "C:\Program Files\Observe\observe-agent"; ./observe-agent diagnose'

#Set up correct config with observe url and token
result = remote_host.run_command(init_command)

#Check diagnose command
result = remote_host.run_command(diagnose_command)
observe_val = False
for line in result.stdout.splitlines():
obs-gh-nikhildua marked this conversation as resolved.
Show resolved Hide resolved
if "Request to test URL responded with response code 200" in line:
print (" ✅ observe-agent -> observe validation passed! ")
observe_val = True
break
if not observe_val:
print(result)
raise ValueError(f"❌ Failed: observe-agent -> observe validation")

pass

@print_test_decorator
def run_test_linux(remote_host: Host, env_vars: dict) -> None:
Expand All @@ -32,7 +64,7 @@ def run_test_linux(remote_host: Host, env_vars: dict) -> None:
observe_val = False
for line in result.stdout.splitlines():
if "Request to test URL responded with response code 200" in line:
print (" ✅ observe-agent -> observe valdation passed! ")
print (" ✅ observe-agent -> observe validation passed! ")
observe_val = True
break
if not observe_val:
Expand All @@ -45,13 +77,16 @@ def run_test_linux(remote_host: Host, env_vars: dict) -> None:
env_vars = get_env_vars(need_observe=True)
remote_host = Host(host_ip=env_vars["host"],
username=env_vars["user"],
key_file_path=env_vars["key_filename"])
key_file_path=env_vars["key_filename"],
password=env_vars["password"])

#Test SSH Connection before starting test of interest
remote_host.test_conection(int(env_vars["machine_config"]["sleep"]))

if "redhat" in env_vars["machine_config"]["distribution"] or "debian" in env_vars["machine_config"]["distribution"]:
run_test_linux(remote_host, env_vars)
elif "windows" in env_vars["machine_config"]["distribution"]:
run_test_windows(remote_host, env_vars)

pass

Expand Down
58 changes: 57 additions & 1 deletion integration/scripts/test_ec2_connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,58 @@
import time
from utils import *

@print_test_decorator
def run_test_windows(remote_host: Host, env_vars: dict) -> None:

"""
This test validates that the UserdataExecution.log finished successfully
and ec2 instance is in stable state prior to running other


Args:
remote_host (Host): instance to ssh into
env_vars (dict): environment variables passed into for testing

Raises:
RuntimeError: Failed to verify UserdataExecution.log or agent.logfile
"""


tmp_file = "/tmp/UserdataExecution.log"
cloud_init_file_timeout = 240 # 4 minutes

if "2022" in env_vars["machine_name"]: #Windows 2022 - Test windows cloud-init file finished successfully
print("Windows 2022 detected")
cloud_init_file = r'/C:/ProgramData/Amazon/EC2Launch/log/agent.log'

for _ in range(cloud_init_file_timeout):
remote_host.get_file(cloud_init_file, tmp_file) # This command will automatically test connection
with open(tmp_file) as file: #No encoding for windows 2022 needed
content = file.read().lower()
if "script execution finished successfully" in content:
print(" ✅ Verified agent.log had completed successfully!")
return
else:
print(" Looking for the agent.log file to finish completing...")
time.sleep(1)
raise RuntimeError("❌ The agent.log file did not finish successfully in time")
else: # Windows 2016/2019 - Test windows cloud-init file finished successfully
print("Windows 2016 or 2019 detected")
cloud_init_file = r'/C:/ProgramData/Amazon/EC2-Windows/Launch/Log/UserdataExecution.log'

for _ in range(cloud_init_file_timeout):
remote_host.get_file(cloud_init_file, tmp_file) # This command will automatically test connection
with open(tmp_file, encoding="utf-16") as file:
content = file.read().lower()
if "user data script completed" in content:
print(" ✅ Verified UserdataExecution had completed successfully!")
return
else:
print(" Looking for the UserdataExecution.log file to finish completing...")
time.sleep(1)
raise RuntimeError("❌ The UserdataExecution file did not finish successfully in time")



@print_test_decorator
def run_test_linux(remote_host: Host, env_vars: dict) -> None:
Expand Down Expand Up @@ -45,12 +97,16 @@ def run_test_linux(remote_host: Host, env_vars: dict) -> None:
env_vars = get_env_vars()
remote_host = Host(host_ip=env_vars["host"],
username=env_vars["user"],
key_file_path=env_vars["key_filename"])
key_file_path=env_vars["key_filename"],
password=env_vars["password"])

#Test SSH Connection before starting test of interest
remote_host.test_conection(int(env_vars["machine_config"]["sleep"]))


if "redhat" in env_vars["machine_config"]["distribution"] or "debian" in env_vars["machine_config"]["distribution"]:
run_test_linux(remote_host, env_vars)
elif "windows" in env_vars["machine_config"]["distribution"]:
run_test_windows(remote_host, env_vars)


Loading
Loading