Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
72 changes: 48 additions & 24 deletions .github/workflows/cypress.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,6 @@ jobs:
- uses: actions/checkout@main
- name: Get branch name
uses: nelonoel/branch-name@v1.0.1
- name: Install snapd and core snaps
run: |
sudo snap install snapd
sudo snap install core26 --candidate
- name: Setup MAAS
uses: canonical/setup-maas@main
with:
Expand Down Expand Up @@ -122,53 +118,81 @@ jobs:
build: yarn build
- name: Create MAAS admin
if: matrix.groups == 'with-users'
run: sudo maas createadmin --username=admin --password=test --email=fake@example.org
run: lxc exec maas-backend -- maas createadmin --username=admin --password=test --email=fake@example.org
- name: Create MAAS non-admin user
if: matrix.groups == 'with-users'
run: |
export API_KEY=`sudo maas apikey --username=admin`
maas login admin http://localhost:5240/MAAS $API_KEY
maas admin users create username=user password=test email=fake-user@example.org is_superuser=0
API_KEY=$(lxc exec maas-backend -- maas apikey --username=admin)
lxc exec maas-backend -- maas login admin http://localhost:5240/MAAS "$API_KEY"
lxc exec maas-backend -- maas admin users create username=user password=test email=fake-user@example.org is_superuser=0
- name: Add Keycloak as OIDC provider in MAAS
if: matrix.groups == 'with-users'
shell: bash
run: |
maas admin oidc-providers create \
# MAAS runs inside the LXD container; resolve the host IP as seen from the
# container so it can reach Keycloak (Docker on the host).
HOST_IP=$(lxc exec maas-backend -- ip route | awk '/default/ {print $3}')
# Export so the Cypress run step can construct the matching cy.origin() URL.
echo "KEYCLOAK_HOST=$HOST_IP" >> $GITHUB_ENV
lxc exec maas-backend -- maas admin oidc-providers create \
name="Keycloak" \
client_id="maas-client" \
client_secret="$KC_CLIENT_SECRET" \
enabled=True \
issuer_url="http://localhost:8080/realms/test-realm" \
issuer_url="http://${HOST_IP}:8080/realms/test-realm" \
token_type="JWT" \
redirect_uri="https://localhost:8400/MAAS/r/login/oidc/callback" \
scopes="openid profile email offline_access"
- name: Enable TLS for MAAS
shell: bash
run: |
echo "Generating self-signed certificate"
sudo mkdir -p /var/snap/maas/common/certs && \
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout /var/snap/maas/common/certs/key.pem \
-out /var/snap/maas/common/certs/cert.pem \
mkdir -p /tmp/maas-certs
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout /tmp/maas-certs/key.pem \
-out /tmp/maas-certs/cert.pem \
-subj "/C=US/ST=State/L=City/O=Org/OU=Unit/CN=localhost" \
-addext "subjectAltName=DNS:localhost,IP:127.0.0.1" && \

echo "y" | sudo maas config-tls enable /var/snap/maas/common/certs/key.pem /var/snap/maas/common/certs/cert.pem
sudo chmod 644 /var/snap/maas/common/certs/key.pem /var/snap/maas/common/certs/cert.pem
-addext "subjectAltName=DNS:localhost,IP:127.0.0.1"

lxc exec maas-backend -- mkdir -p /var/snap/maas/common/certs
lxc file push /tmp/maas-certs/key.pem maas-backend/var/snap/maas/common/certs/key.pem
lxc file push /tmp/maas-certs/cert.pem maas-backend/var/snap/maas/common/certs/cert.pem
lxc exec maas-backend -- chmod 644 /var/snap/maas/common/certs/key.pem /var/snap/maas/common/certs/cert.pem

echo "y" | lxc exec maas-backend -- maas config-tls enable \
/var/snap/maas/common/certs/key.pem \
/var/snap/maas/common/certs/cert.pem

# Forward the HTTPS port from the host to the container
MAAS_IP=$(lxc query /1.0/containers/maas-backend/state | jq -r '.network.eth0.addresses[0].address')
sudo socat TCP-LISTEN:5443,fork,reuseaddr TCP:${MAAS_IP}:5443 &
- name: Trust self-signed certificate
run: |
sudo cp /var/snap/maas/common/certs/cert.pem /usr/local/share/ca-certificates/maas-selfsigned.crt
# Trust on the host (for Cypress / socat-proxied connections)
sudo cp /tmp/maas-certs/cert.pem /usr/local/share/ca-certificates/maas-selfsigned.crt
sudo update-ca-certificates
# Trust inside the LXD container (for maas CLI → HTTPS MAAS API calls)
lxc file push /tmp/maas-certs/cert.pem maas-backend/usr/local/share/ca-certificates/maas-selfsigned.crt
lxc exec maas-backend -- update-ca-certificates
- name: Wait for MAAS boot resources
if: matrix.groups == 'with-users'
shell: bash
run: while [ $(maas admin boot-resources is-importing -k | cat) == "true" ]; do sleep 10; done; echo "syncing finished"
run: |
# TLS is now enabled; re-login using the HTTPS endpoint inside the container
API_KEY=$(lxc exec maas-backend -- maas apikey --username=admin)
lxc exec maas-backend -- maas login admin https://localhost:5443/MAAS "$API_KEY"
lxc exec maas-backend -- bash -c 'while [ $(maas admin boot-resources is-importing -k | cat) == "true" ]; do sleep 10; done; echo "syncing finished"'
- name: Run Cypress tests
uses: cypress-io/github-action@v4
env:
HTTPS_CERT: /var/snap/maas/common/certs/cert.pem
HTTPS_KEY: /var/snap/maas/common/certs/key.pem
NODE_EXTRA_CA_CERTS: /var/snap/maas/common/certs/cert.pem
HTTPS_CERT: /tmp/maas-certs/cert.pem
HTTPS_KEY: /tmp/maas-certs/key.pem
NODE_EXTRA_CA_CERTS: /tmp/maas-certs/cert.pem
# cy.origin() in the SSO login step needs to match the origin the browser
# is actually redirected to — the Keycloak authorization URL embeds HOST_IP
# (the LXD default-gateway IP on which Docker publishes Keycloak port 8080).
CYPRESS_KEYCLOAK_URL: http://${{ env.KEYCLOAK_HOST }}
CYPRESS_KEYCLOAK_PORT: 8080
with:
config: baseUrl=${{env.MAAS_UI_URL}},pageLoadTimeout=100000
install: false
Expand All @@ -184,7 +208,7 @@ jobs:
- name: Collect MAAS logs
if: failure()
shell: bash
run: journalctl -u snap.maas.pebble.service --since="1 hour ago" > cypress/maas_logs.txt
run: lxc exec maas-backend -- journalctl -u snap.maas.pebble.service --since="1 hour ago" > cypress/maas_logs.txt
- uses: actions/upload-artifact@v4
if: failure()
with:
Expand Down
11 changes: 6 additions & 5 deletions cypress/e2e/with-users/features/login/login.feature
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,9 @@ Scenario: The user is logged in and redirected to the machine list page if setup
When the user provides correct username and password
Then the pathname should equal "/machines"

Scenario: The user is logged in via SSO and redirected to the machine list page if setup and user intros are skipped
Given the skipsetupintro cookie is set to "true"
Given the skipintro cookie is set to "true"
When the user clicks on the "Login with keycloak" button
Then the pathname should equal "/machines"
#TODO: re-enable after setup-maas is rolled back to use the snap
#Scenario: The user is logged in via SSO and redirected to the machine list page if setup and user intros are skipped
# Given the skipsetupintro cookie is set to "true"
# Given the skipintro cookie is set to "true"
# When the user clicks on the "Login with keycloak" button
# Then the pathname should equal "/machines"
26 changes: 12 additions & 14 deletions cypress/e2e/with-users/features/machines/machines_list.feature
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,25 @@ Feature: Machine listing
Then the machines grid for "<group by>" should exist

Examples:
| group by |
| No grouping |
| Group by status |
| Group by owner |
| Group by resource pool |
| Group by architecture |
| Group by domain |
| Group by parent |
| Group by KVM |
| Group by KVM type |
| Group by power state |
| Group by zone |
| group by |
| No grouping |
| Group by status |
| Group by owner |
| Group by resource pool |
| Group by architecture |
| Group by domain |
| Group by parent |
| Group by KVM |
| Group by KVM type |
| Group by power state |
| Group by zone |

Scenario: Displays machine counts with active filters
Given there are commissioning machines matching a generated hostname
When the user groups machines by status
And the user filters machines by the generated hostname and commissioning status
Then the text "Showing 2 out of 2 machines" should be visible
When the user selects the commissioning group
And the user deletes the selected machines
Then the delete 2 machines confirmation should be handled successfully

Scenario: Replaces the URL when selecting filters
Given the user has visited the network discovery page
Expand Down
7 changes: 5 additions & 2 deletions cypress/support/step_definitions/common/navigation.steps.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Given, Then } from "@badeball/cypress-cucumber-preprocessor";
import { routes } from "../../../constants";
import { routes, VERY_LONG_TIMEOUT } from "../../../constants";
import { generateMAASURL } from "../../../e2e/utils";

const escapeRegExp = (value: string) =>
Expand All @@ -26,5 +26,8 @@ Then("the pathname should equal {string}", (expectedPath: string) => {
return;
}

cy.location("pathname").should("eq", expectedFullPath);
cy.location("pathname", { timeout: VERY_LONG_TIMEOUT }).should(
"eq",
expectedFullPath
);
});
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
Then,
When,
} from "@badeball/cypress-cucumber-preprocessor";
import { LONG_TIMEOUT } from "../../../constants";
import { LONG_TIMEOUT, VERY_LONG_TIMEOUT } from "../../../constants";
import { generateMAASURL, generateName } from "../../../e2e/utils";

const GROUP_BY_OPTIONS = [
Expand Down Expand Up @@ -238,7 +238,7 @@ Then(

cy.findByRole("searchbox").clear().type(state.searchFilter);
cy.findByText(/No machines match the search criteria./, {
timeout: LONG_TIMEOUT,
timeout: VERY_LONG_TIMEOUT,
}).should("exist");
}
);
Expand Down
Loading