Installing Rancher with ansible - Lesson 2

Author: Stu Feeser

Objective

✅ Observe the manual process first
✅ Make it clear what we must automate
✅ Choose the right tools
✅ Discover that ansible has no intrinsic ability to access a web page like a human
✅ Explain whey “headless” operation is best for ansible
✅ Compare Puppeteer with Selenium
✅ Develop a conceptual understanding of working puppeteer code
✅ Observe a working example of puppeteer in action

Procedure:

  1. Let’s take a look at the bootstrap password we created in the previous lab.

    student@controller-1:~$ cat ~/pswd.txt

    ldt68zzbn6cqk5922wdbb57z54t8rj9j5mzngwq6gxwfl82vhfgss5
    ** YOURS WILL BE DIFFERENT **
  2. Open the Rancher web page.

    Our demo uses the Channel Changer Button to access the rancher web page

    admin login admin login

  3. Enter the bootstrap password you saved from the last lab

  4. Click Login with Local User

  5. Select “Set a specific password to use” and configure your sign-up page with the following:

    • New Password: rancherisgr8

    • Uncheck: Allow collection of anonymous statistics

    • Check: I agree to the terms and conditions for using Rancher

    • 🖰 Click the 'Continue' button

    • Congratulations! You’ve configured you admin user and loaded the Rancher Home Page!

    Warning! Do not edit the Server URL.

  6. In the future, you will log in to SUSE Rancher with the following credentials:

    Username: admin

    Password: rancherisgr8

  7. Ansible alone cannot automate the process just demonstrated. A tool is needed that can emulate a human interacting with a web page is required. There are many options for doing this. Two of the most popular are Selenium and Puppeteer. We will use Puppeteer in this demonstration as Puppeteer is designed to operate flawlessly in headless mode. Since we just added three new vocabular words, let’s review those new terms:

    headless Mode: This means there is no keyboard and monitor involved in the operatation, which is exactly how ansible works. Nearly always, CI/CD pipelines require headless operation.

    Selenium: A testing suite that is able to emulate many browsers, when the mission demands testing web site behavior for different browser types. Selenium is very powerful, but overkill for this application. Furthermore, Selenium does not run natively in headless mode.

    Puppeteer: A testing suite that only emulates google chrome, but works perfectly in headless mode, and is coded using javascript, of which both of these are perfect for this application. Therefore this demo requires us to write a puppeteer script to perform the password change.

  8. We need a new environment to test our puppeteer script, so we will move to a new environment with the rancher container running, ready to reset the password, hence, “One Enternity Later…”

    Make sure to run the steps from Lesson 1 in order to get rancher installed and up and running.

  9. With a freshly installed system let’s review the puppeteer script below which will perform the process we did manually.

    vim update_rancher_passwd_w_puppeteer.js

    const fs = require('fs');
    const puppeteer = require('puppeteer');
    
    // ✅ Step 1: Get the new password from the command line
    const newPassword = process.argv[2];
    
    if (!newPassword) {
      console.error("� Error: Please provide a new password as a command-line argument.");
      console.error("Usage: node rancher_setup.js 'YourNewPassword123'");
      process.exit(1);
    }
    
    // ✅ Step 2: Read the hash password from the file
    const passwordFilePath = '/home/student/pswd.txt';
    
    if (!fs.existsSync(passwordFilePath)) {
      console.error(`� Error: Password file not found at ${passwordFilePath}`);
      console.error("Please create the file and add the hash password.");
      console.error("Example: echo 'yourhashedpassword' > /home/student/pswd.txt");
      process.exit(1);
    }
    
    const hashPassword = fs.readFileSync(passwordFilePath, 'utf8').trim();
    
    // ✅ Step 3: Start Puppeteer Automation
    (async () => {
      const browser = await puppeteer.launch({
        headless: true, // Set to false for debugging
        ignoreHTTPSErrors: true,
        args: [
          '--ignore-certificate-errors',
          '--no-sandbox',
          '--disable-setuid-sandbox'
        ]
      });
    
      const page = await browser.newPage();
    
      // -------------------------------
      // Step 4: Open Rancher Setup Page
      // -------------------------------
      console.log("Opening initial Rancher setup page...");
      await page.goto('https://controller-1', { waitUntil: 'networkidle2', timeout: 10000 });
    
      // Wait for the password field (the one expecting the default hash)
      await page.waitForSelector('#password', { visible: true, timeout: 10000 });
      console.log("Filling in the hash password...");
      await page.type('#password', hashPassword);
    
      // Wait for and click the submit button
      await page.waitForSelector('#submit', { visible: true, timeout: 10000 });
      console.log("Submitting hash password...");
      await page.click('#submit');
    
      // -------------------------------
      // Step 5: Change the Default Password
      // -------------------------------
      const radioSelector = 'span[aria-label="Set a specific password to use"]';
      await page.waitForSelector(radioSelector, { visible: true, timeout: 10000 });
      await page.click(radioSelector);
    
      console.log(`Setting new password: ${'*'.repeat(newPassword.length)}`);
    
      const newPasswordSelector = 'div[data-testid="setup-password"] input[type="password"]';
      await page.waitForSelector(newPasswordSelector, { visible: true, timeout: 10000 });
      await page.type(newPasswordSelector, newPassword);
    
      const confirmPasswordSelector = 'div[data-testid="setup-password-confirm"] input[type="password"]';
      await page.waitForSelector(confirmPasswordSelector, { visible: true, timeout: 10000 });
      await page.type(confirmPasswordSelector, newPassword);
    
      // -------------------------------
      // Step 6: Accept EULA Agreement
      // -------------------------------
      console.log("Checking the EULA agreement...");
      const eulaSelector = 'div[data-testid="setup-agreement"] label[for="checkbox-eula"] span.checkbox-custom';
      await page.waitForSelector(eulaSelector, { visible: true, timeout: 10000 });
      await page.click(eulaSelector);
    
      // -------------------------------
      // Step 7: Submit the Form
      // -------------------------------
      console.log("Taking full-page screenshot before clicking the continue button...");
      await page.screenshot({ path: 'pre_submit.png', fullPage: true });
    
      console.log("Clicking the continue button...");
      await page.click('#submit button');
    
      await new Promise(resolve => setTimeout(resolve, 5000));
    
      console.log("Setup complete.");
      await browser.close();
    })();
  10. Now run the script manually and test.

    node update_rancher_passwd_w_puppeteer.js 'yournewpassword'

← Previous Next →