-
Notifications
You must be signed in to change notification settings - Fork 50
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
tests(e2e): Configure AD before starting test suite #828
Merged
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
9c1e9c7
Monkey patch samba GPO XML fix in our converter
GabrielNagy 7968b33
Restructure GPO and other assets used in e2e tests
GabrielNagy cb23806
Update file upload to create target directory
GabrielNagy f666ce2
Add step to prepare domain controller for testing
GabrielNagy 93b8cee
Standardize on E2E SSH key path
GabrielNagy b94ed17
Ignore converted POL files under e2e path
GabrielNagy File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Happy to obfuscate this "secret" - we would need a separate env variable to store the user password and pass it to this script via CLI argument from Go.
As an alternative, to avoid password authentication altogether, we can use a global authorized key file to be able to SSH as any account using the same key (as described in https://serverfault.com/questions/434896/ssh-one-authorized-keys-for-multiple-service-accounts). I kind of prefer this solution.