at master 5.2 kB view raw
1{ pkgs, lib, ... }: 2 3let 4 user = "alice"; # from ./common/user-account.nix 5 password = "foobar"; # from ./common/user-account.nix 6in 7{ 8 name = "cockpit"; 9 meta = { 10 maintainers = with lib.maintainers; [ lucasew ]; 11 }; 12 nodes = { 13 server = 14 { config, ... }: 15 { 16 imports = [ ./common/user-account.nix ]; 17 security.polkit.enable = true; 18 users.users.${user} = { 19 extraGroups = [ "wheel" ]; 20 }; 21 services.cockpit = { 22 enable = true; 23 port = 7890; 24 openFirewall = true; 25 allowed-origins = [ 26 "https://server:${toString config.services.cockpit.port}" 27 ]; 28 }; 29 }; 30 client = 31 { config, ... }: 32 { 33 imports = [ ./common/user-account.nix ]; 34 environment.systemPackages = 35 let 36 seleniumScript = 37 pkgs.writers.writePython3Bin "selenium-script" 38 { 39 libraries = with pkgs.python3Packages; [ selenium ]; 40 } 41 '' 42 from selenium import webdriver 43 from selenium.webdriver.common.by import By 44 from selenium.webdriver.firefox.options import Options 45 from selenium.webdriver.support.ui import WebDriverWait 46 from selenium.webdriver.support import expected_conditions as EC 47 from time import sleep 48 49 50 def log(msg): 51 from sys import stderr 52 print(f"[*] {msg}", file=stderr) 53 54 55 log("Initializing") 56 57 options = Options() 58 options.add_argument("--headless") 59 60 service = webdriver.FirefoxService(executable_path="${lib.getExe pkgs.geckodriver}") # noqa: E501 61 driver = webdriver.Firefox(options=options, service=service) 62 63 driver.implicitly_wait(10) 64 65 log("Opening homepage") 66 driver.get("https://server:7890") 67 68 69 def wait_elem(by, query, timeout=10): 70 wait = WebDriverWait(driver, timeout) 71 wait.until(EC.presence_of_element_located((by, query))) 72 73 74 def wait_title_contains(title, timeout=10): 75 wait = WebDriverWait(driver, timeout) 76 wait.until(EC.title_contains(title)) 77 78 79 def find_element(by, query): 80 return driver.find_element(by, query) 81 82 83 def set_value(elem, value): 84 script = 'arguments[0].value = arguments[1]' 85 return driver.execute_script(script, elem, value) 86 87 88 log("Waiting for the homepage to load") 89 90 # cockpit sets initial title as hostname 91 wait_title_contains("server") 92 wait_elem(By.CSS_SELECTOR, 'input#login-user-input') 93 94 log("Homepage loaded!") 95 96 log("Filling out username") 97 login_input = find_element(By.CSS_SELECTOR, 'input#login-user-input') 98 set_value(login_input, "${user}") 99 100 log("Filling out password") 101 password_input = find_element(By.CSS_SELECTOR, 'input#login-password-input') 102 set_value(password_input, "${password}") 103 104 log("Submitting credentials for login") 105 driver.find_element(By.CSS_SELECTOR, 'button#login-button').click() 106 107 # driver.implicitly_wait(1) 108 # driver.get("https://server:7890/system") 109 110 log("Waiting dashboard to load") 111 wait_title_contains("${user}@server") 112 113 log("Waiting for the frontend to initialize") 114 sleep(1) 115 116 log("Looking for that banner that tells about limited access") 117 container_iframe = find_element(By.CSS_SELECTOR, 'iframe.container-frame') 118 driver.switch_to.frame(container_iframe) 119 120 assert "Web console is running in limited access mode" in driver.page_source 121 122 log("Clicking the sudo button") 123 for button in driver.find_elements(By.TAG_NAME, "button"): 124 if 'admin' in button.text: 125 button.click() 126 driver.switch_to.default_content() 127 128 log("Checking that /nonexistent is not a thing") 129 assert '/nonexistent' not in driver.page_source 130 assert len(driver.find_elements(By.CSS_SELECTOR, '#machine-reconnect')) == 0 131 132 driver.close() 133 ''; 134 in 135 with pkgs; 136 [ 137 firefox-unwrapped 138 geckodriver 139 seleniumScript 140 ]; 141 }; 142 }; 143 144 testScript = '' 145 start_all() 146 147 server.wait_for_unit("sockets.target") 148 server.wait_for_open_port(7890) 149 150 client.succeed("curl -k https://server:7890 -o /dev/stderr") 151 print(client.succeed("whoami")) 152 client.succeed('PYTHONUNBUFFERED=1 selenium-script') 153 ''; 154}