-
Notifications
You must be signed in to change notification settings - Fork 50
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
tests(e2e): Configure AD before starting test suite (#828)
tests(e2e): Configure AD before starting test suite
- Loading branch information
Showing
23 changed files
with
288 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
[General] | ||
Version=42 | ||
displayName=New Group Policy Object |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
[General] | ||
Version=42 | ||
displayName=New Group Policy Object |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
[General] | ||
Version=42 | ||
displayName=New Group Policy Object |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
// Package main provides a script to prepare OU and GPO configuration on the | ||
// domain controller, converting XML GPOs to binary POL format and staging them | ||
// in the SYSVOL share. | ||
package main | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"os" | ||
"os/exec" | ||
"path/filepath" | ||
|
||
log "github.com/sirupsen/logrus" | ||
"github.com/ubuntu/adsys/e2e/internal/command" | ||
"github.com/ubuntu/adsys/e2e/internal/inventory" | ||
"github.com/ubuntu/adsys/e2e/internal/remote" | ||
"github.com/ubuntu/adsys/e2e/scripts" | ||
) | ||
|
||
var sshKey string | ||
|
||
func main() { | ||
os.Exit(run()) | ||
} | ||
|
||
func run() int { | ||
cmd := command.New(action, | ||
command.WithValidateFunc(validate), | ||
command.WithStateTransition(inventory.ClientProvisioned, inventory.ADProvisioned), | ||
) | ||
cmd.Usage = fmt.Sprintf(`go run ./%s [options] | ||
Prepare OU and GPO configuration on the domain controller. | ||
The AD password must be set in the AD_PASSWORD environment variable. | ||
This script will: | ||
- convert XML GPOs in the e2e/gpo directory to POL format | ||
- upload the GPO structure to the domain controller | ||
- upload & run a PowerShell script to the domain controller responsible for creating the required resources`, filepath.Base(os.Args[0])) | ||
|
||
return cmd.Execute(context.Background()) | ||
} | ||
|
||
func validate(_ context.Context, cmd *command.Command) error { | ||
var err error | ||
sshKey, err = command.ValidateAndExpandPath(cmd.Inventory.SSHKeyPath, command.DefaultSSHKeyPath) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func action(ctx context.Context, cmd *command.Command) error { | ||
gpoDir, err := scripts.GPODir() | ||
if err != nil { | ||
return err | ||
} | ||
scriptsDir, err := scripts.Dir() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// Convert XML GPOs to POL format | ||
// #nosec G204: this is only for tests, under controlled args | ||
out, err := exec.CommandContext(ctx, "python3", filepath.Join(scriptsDir, "xml_to_pol.py"), gpoDir).CombinedOutput() | ||
if err != nil { | ||
return fmt.Errorf("failed to convert GPOs to POL format: %w\n%s", err, out) | ||
} | ||
log.Debugf("xml_to_pol.py output:\n%s", out) | ||
|
||
// Establish remote connection | ||
client, err := remote.NewClient(inventory.DomainControllerIP, "localadmin", sshKey) | ||
if err != nil { | ||
return err | ||
} | ||
defer client.Close() | ||
|
||
// Recursively upload the GPO structure to the domain controller | ||
if err := filepath.Walk(gpoDir, func(path string, info os.FileInfo, err error) error { | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// We only need to copy files | ||
if info.IsDir() { | ||
return nil | ||
} | ||
|
||
// Get the relative path of the file | ||
relPath, err := filepath.Rel(gpoDir, path) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// Upload the file | ||
remotePath := filepath.Join("C:", "Temp", cmd.Inventory.Hostname, relPath) | ||
if err := client.Upload(path, remotePath); err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
}); err != nil { | ||
return fmt.Errorf("failed to upload GPOs to domain controller: %w", err) | ||
} | ||
|
||
// Upload the PowerShell script to the domain controller | ||
if err := client.Upload(filepath.Join(scriptsDir, "prepare-ad.ps1"), filepath.Join("C:", "Temp", cmd.Inventory.Hostname)); err != nil { | ||
return err | ||
} | ||
|
||
// Run the PowerShell script | ||
if _, err := client.Run(ctx, fmt.Sprintf("powershell.exe -ExecutionPolicy Bypass -File %s -hostname %s", filepath.Join("C:", "Temp", cmd.Inventory.Hostname, "prepare-ad.ps1"), cmd.Inventory.Hostname)); err != nil { | ||
return fmt.Errorf("error running the PowerShell script: %w", err) | ||
} | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
# Description: Prepare the domain controller for E2E testing | ||
# | ||
# The script takes a single argument, the hostname of the Linux client to be tested. | ||
# It creates the following OU structure, together with GPOs and users: | ||
# DC=warthogs,DC=biz | ||
# └── $hostname | ||
# ├── users <──────── linked to $hostname-users-gpo | ||
# │ ├── admins <─── linked to $hostname-admins-gpo | ||
# │ │ └── 👤 $hostname-adm | ||
# │ └── 👤 $hostname-usr | ||
# ├── computers <──── linked to $hostname-computers-gpo | ||
# │ └── 💻 $hostname | ||
# └── out-of-tree | ||
# | ||
# The script assumes the GPO data is stored in the same directory - this is the | ||
# case when ran via the ./cmd/provision_resources/02_provision_ad command. | ||
# | ||
# The script is not idempotent, it will fail if any resources already exist. | ||
param ( | ||
[string]$hostname | ||
) | ||
|
||
# Uncomment to dry run the script | ||
# $WhatIfPreference = $true | ||
|
||
# Stop on first error | ||
$ErrorActionPreference = "Stop" | ||
|
||
# Create parent OU | ||
$parentOUPath = "DC=warthogs,DC=biz" | ||
New-ADOrganizationalUnit -Name $hostname -Path $parentOUPath -ProtectedFromAccidentalDeletion $false | ||
|
||
$organizationalUnits = @{ | ||
'users' = "OU=${hostname},${parentOUPath}" | ||
'computers' = "OU=${hostname},${parentOUPath}" | ||
'admins' = "OU=users,OU=${hostname},${parentOUPath}" | ||
'out-of-tree' = "OU=${hostname},${parentOUPath}" | ||
} | ||
|
||
# Create child OUs | ||
foreach ($ou in $organizationalUnits.GetEnumerator()) { | ||
New-ADOrganizationalUnit -Name $ou.Key -Path $ou.Value -ProtectedFromAccidentalDeletion $false | ||
} | ||
|
||
# Prepare GPOs | ||
# POL files are stored in the same directory as this script | ||
$gpoPaths = 'users', 'users-admins', 'computers' | ||
foreach ($gpoPath in $gpoPaths) { | ||
$targetOU = $gpoPath.split('-')[-1] | ||
$targetOUPath = $organizationalUnits[$targetOU] | ||
|
||
$gpoName = "$hostname-$targetOU-gpo" | ||
$gpo = New-GPO -Name $gpoName -Comment $hostname | ||
|
||
# Copy path to SYSVOL | ||
$sourceDir = Join-Path -Path $PSScriptRoot -ChildPath $gpoPath | ||
$destinationDir = "\\warthogs.biz\SYSVOL\warthogs.biz\Policies\{$($gpo.Id)}" | ||
Copy-Item -Path "$sourceDir\*" -Destination $destinationDir -Recurse -Force | ||
|
||
# Link GPO to OU | ||
New-GPLink -Name $gpoName -Target "OU=${targetOU},${targetOUPath}" -LinkEnabled Yes | ||
} | ||
|
||
# Create users | ||
$password = ConvertTo-SecureString -String 'supersecretpassword' -AsPlainText -Force | ||
New-ADUser -Name "${hostname}-usr" -Path "OU=users,$($organizationalUnits['users'])" -AccountPassword $password -Enabled $true | ||
New-ADUser -Name "${hostname}-adm" -Path "OU=admins,$($organizationalUnits['admins'])" -AccountPassword $password -Enabled $true | ||
|
||
# Move machine to computers OU | ||
$identity = Get-ADComputer -Identity $hostname | ||
Move-ADObject -Identity $identity -TargetPath "OU=computers,$($organizationalUnits['computers'])" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters