Skip to content

Commit eb145c3

Browse files
authored
Backport PRs #392 and #421 to 3.3
* Fix MDS Selector for Workload Management Dashboards (#421) Signed-off-by: Lingxi Chen <[email protected]> * Security attribute feature for WLM dashboard (#392) Signed-off-by: Lingxi Chen <[email protected]>
1 parent 467223b commit eb145c3

27 files changed

+2609
-547
lines changed
Lines changed: 287 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,287 @@
1+
name: Cypress e2e integration tests workflow with security
2+
on:
3+
pull_request:
4+
branches:
5+
- "*"
6+
push:
7+
branches:
8+
- "*"
9+
env:
10+
OS_BRANCH: "3.3"
11+
SECURITY_ENABLED: "true"
12+
VERSION: "3.3.2"
13+
OPENSEARCH_INITIAL_ADMIN_PASSWORD: "myStrongPassword123!"
14+
jobs:
15+
tests:
16+
name: Run Cypress E2E tests for WLM
17+
timeout-minutes: 90
18+
strategy:
19+
fail-fast: false
20+
matrix:
21+
os: [ ubuntu-latest ]
22+
include:
23+
- os: ubuntu-latest
24+
cypress_cache_folder: ~/.cache/Cypress
25+
runs-on: ${{ matrix.os }}
26+
env:
27+
# prevents extra Cypress installation progress messages
28+
CI: 1
29+
# avoid warnings like "tput: No value for $TERM and no -T specified"
30+
TERM: xterm
31+
# make Node run in ipv4 first so that cypress can detect 5601 port in CI environment
32+
NODE_OPTIONS: '--max-old-space-size=6144 --dns-result-order=ipv4first'
33+
# 2.12 onwards security demo configuration require a custom admin password
34+
OPENSEARCH_INITIAL_ADMIN_PASSWORD: 'myStrongPassword123!'
35+
steps:
36+
- name: Checkout Branch
37+
uses: actions/checkout@v3
38+
- name: Set up JDK
39+
uses: actions/setup-java@v1
40+
with:
41+
java-version: 21
42+
- name: Checkout cypress-test
43+
uses: actions/checkout@v2
44+
with:
45+
repository: ${{github.repository}}
46+
path: cypress-test
47+
48+
- name: Checkout Security
49+
uses: actions/checkout@v4
50+
with:
51+
repository: opensearch-project/security
52+
path: security
53+
ref: ${{ env.OS_BRANCH }}
54+
55+
- name: Build Security plugin
56+
run: |
57+
set -e
58+
cd security
59+
./gradlew --no-daemon assemble
60+
61+
echo "Checking security build directory:"
62+
ls -la build/distributions/
63+
64+
cp build/distributions/opensearch-security-*.zip "$GITHUB_WORKSPACE/security.zip"
65+
ls -lh "$GITHUB_WORKSPACE/security.zip"
66+
67+
- name: Checkout OpenSearch
68+
uses: actions/checkout@v4
69+
with:
70+
path: OpenSearch
71+
repository: opensearch-project/OpenSearch
72+
ref: ${{ env.OS_BRANCH }}
73+
74+
- name: Build WLM plugin from OpenSearch
75+
run: |
76+
set -e
77+
echo "Using OpenSearch branch: $OS_BRANCH"
78+
cd OpenSearch
79+
80+
# Build ONLY the workload-management plugin
81+
./gradlew :plugins:workload-management:clean :plugins:workload-management:assemble \
82+
-Dopensearch.version=${{ env.VERSION }} --no-daemon
83+
84+
echo "Checking WLM build directory:"
85+
ls -la plugins/workload-management/build/distributions/
86+
87+
cp plugins/workload-management/build/distributions/workload-management-*.zip "$GITHUB_WORKSPACE/wlm.zip"
88+
ls -lh "$GITHUB_WORKSPACE/wlm.zip"
89+
90+
- name: Run Opensearch with A Single Plugin
91+
uses: derek-ho/start-opensearch@v9
92+
with:
93+
opensearch-version: ${{ env.VERSION }}
94+
plugins: "file:$GITHUB_WORKSPACE/security.zip,file:$GITHUB_WORKSPACE/wlm.zip"
95+
security-enabled: true
96+
admin-password: ${{ env.OPENSEARCH_INITIAL_ADMIN_PASSWORD }}
97+
jdk-version: 21
98+
99+
- name: Enable WLM (with or without Security) and verify
100+
run: |
101+
set -e
102+
echo "Enabling Workload Management (WLM)..."
103+
104+
# Detect whether security is enabled
105+
if [ "$SECURITY_ENABLED" = 'true' ]; then
106+
echo "Security detected — using HTTPS with credentials"
107+
PROTOCOL=https
108+
AUTH="-u admin:${OPENSEARCH_INITIAL_ADMIN_PASSWORD}"
109+
CURL_FLAGS="--insecure --fail-with-body"
110+
else
111+
echo "No security detected — using HTTP without credentials"
112+
PROTOCOL=http
113+
AUTH=""
114+
CURL_FLAGS="--fail-with-body"
115+
fi
116+
117+
# Enable WLM
118+
curl -sS -k --http1.1 $CURL_FLAGS $AUTH \
119+
-X PUT "${PROTOCOL}://localhost:9200/_cluster/settings" \
120+
-H 'Content-Type: application/json' \
121+
-d '{"persistent":{"wlm.workload_group.mode":"enabled"}}'
122+
123+
# Show WLM mode
124+
SETTINGS=$(curl -sS -k --http1.1 -u "admin:${OPENSEARCH_INITIAL_ADMIN_PASSWORD}" "https://localhost:9200/_cluster/settings")
125+
echo "Raw settings response: $SETTINGS"
126+
echo "$SETTINGS" | jq -r '.persistent.wlm.workload_group.mode // "undefined"'
127+
128+
# Test WLM stats endpoint
129+
echo -e "Testing WLM stats endpoint:"
130+
curl -ksu "admin:${OPENSEARCH_INITIAL_ADMIN_PASSWORD}" https://localhost:9200/_wlm/workload_group | jq '.'
131+
132+
- name: Checkout OpenSearch-Dashboards
133+
uses: actions/checkout@v4
134+
with:
135+
repository: opensearch-project/OpenSearch-Dashboards
136+
path: OpenSearch-Dashboards
137+
ref: ${{ env.OS_BRANCH }}
138+
139+
- name: Configure OpenSearch Dashboards for Cypress (heredoc)
140+
run: |
141+
set -euo pipefail
142+
FILE="OpenSearch-Dashboards/config/opensearch_dashboards.yml"
143+
test -f "$FILE" || { echo "Missing $FILE"; exit 1; }
144+
145+
{
146+
printf '%s\n' 'server.host: "0.0.0.0"'
147+
printf '%s\n' 'opensearch.hosts: ["https://localhost:9200"]'
148+
printf '%s\n' 'opensearch.ssl.verificationMode: none'
149+
} >> "$FILE"
150+
151+
echo "=== Last 60 lines of $FILE (show appended settings) ==="
152+
tail -n 60 "$FILE" || true
153+
154+
- name: Checkout Query Insights Dashboards plugin
155+
uses: actions/checkout@v4
156+
with:
157+
path: OpenSearch-Dashboards/plugins/query-insights-dashboards
158+
159+
- name: Setup Node
160+
uses: actions/setup-node@v3
161+
with:
162+
node-version-file: './OpenSearch-Dashboards/.nvmrc'
163+
registry-url: 'https://registry.npmjs.org'
164+
165+
- name: Install Yarn
166+
shell: bash
167+
run: |
168+
YARN_VERSION=$(node -p "require('./OpenSearch-Dashboards/package.json').engines.yarn")
169+
echo "Installing yarn@$YARN_VERSION"
170+
npm i -g yarn@$YARN_VERSION
171+
- run: node -v
172+
- run: yarn -v
173+
174+
- name: Bootstrap plugin/OpenSearch-Dashboards
175+
run: |
176+
cd OpenSearch-Dashboards/plugins/query-insights-dashboards
177+
yarn osd bootstrap --single-version=loose
178+
179+
- name: Run OpenSearch-Dashboards server
180+
run: |
181+
cd OpenSearch-Dashboards
182+
export NODE_OPTIONS="--max-old-space-size=6144 --dns-result-order=ipv4first"
183+
echo "Starting Dashboards..."
184+
nohup yarn start --no-base-path --no-watch --server.host="0.0.0.0" > dashboards.log 2>&1 &
185+
sleep 10
186+
echo "Initial Dashboards log output:"
187+
head -n 100 dashboards.log || true
188+
shell: bash
189+
190+
- name: Wait for OpenSearch-Dashboards to be ready
191+
run: |
192+
echo "Waiting for OpenSearch-Dashboards to start..."
193+
max_attempts=180
194+
attempt=0
195+
while [ $attempt -lt $max_attempts ]; do
196+
code=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:5601/api/status || true)
197+
if [ "$code" = "200" ]; then
198+
state=$(curl -s http://localhost:5601/api/status | jq -r '.status.overall.state // .status.overall.level // "unknown"')
199+
echo "OpenSearch-Dashboards is ready (state=$state)"
200+
break
201+
fi
202+
attempt=$((attempt + 1))
203+
echo "Attempt $attempt/$max_attempts: /api/status -> $code; waiting 10s..."
204+
if [ $((attempt % 10)) -eq 0 ]; then
205+
echo "=== tail dashboards.log ==="
206+
tail -n 120 OpenSearch-Dashboards/dashboards.log || true
207+
echo "=== tail $LOCAL_DISTRO/os.log ==="
208+
tail -n 200 OpenSearch/$LOCAL_DISTRO/os.log || true
209+
echo "==========================="
210+
fi
211+
sleep 10
212+
done
213+
[ $attempt -lt $max_attempts ] || { echo "Timeout waiting for Dashboards"; tail -n 200 OpenSearch-Dashboards/dashboards.log || true; exit 1; }
214+
215+
- name: Verify services are running
216+
run: |
217+
echo "Checking OpenSearch status..."
218+
curl -ksu admin:myStrongPassword123! https://localhost:9200/_cluster/health | jq '.' || echo "OpenSearch not responding"
219+
220+
echo "Checking OpenSearch-Dashboards status..."
221+
echo "=== Full OpenSearch-Dashboards Status ==="
222+
curl -s http://localhost:5601/api/status || echo "OpenSearch-Dashboards not responding"
223+
echo "========================================"
224+
225+
echo "Checking OpenSearch-Dashboards overall state..."
226+
curl -s http://localhost:5601/api/status | jq '.status.overall.state' || echo "Could not extract overall state"
227+
228+
echo "Checking plugin endpoint..."
229+
# 1) login and store session cookie
230+
curl -s -c cookies.txt -X POST 'http://localhost:5601/auth/login' \
231+
-H 'osd-xsrf: true' -H 'Content-Type: application/json' \
232+
--data "{\"username\":\"admin\",\"password\":\"${OPENSEARCH_INITIAL_ADMIN_PASSWORD}\"}" >/dev/null
233+
234+
# 2) hit the app route using the cookie
235+
curl -s -b cookies.txt -o /dev/null -w "HTTP:%{http_code}\n" \
236+
'http://localhost:5601/app/query-insights-dashboards' || echo "Plugin endpoint not accessible"
237+
shell: bash
238+
continue-on-error: true
239+
240+
- name: Install Cypress
241+
run: |
242+
cd OpenSearch-Dashboards/plugins/query-insights-dashboards
243+
npx cypress install
244+
shell: bash
245+
246+
- name: Get Cypress version
247+
id: cypress_version
248+
run: |
249+
cd OpenSearch-Dashboards/plugins/query-insights-dashboards
250+
echo "::set-output name=cypress_version::$(cat ./package.json | jq '.dependencies.cypress' | tr -d '"')"
251+
252+
- name: Cache Cypress
253+
id: cache-cypress
254+
uses: actions/cache@v4
255+
with:
256+
path: ${{ matrix.cypress_cache_folder }}
257+
key: cypress-cache-v2-${{ matrix.os }}-${{ hashFiles('OpenSearch-Dashboards/plugins/query-insights-dashboards/package.json') }}
258+
259+
- name: Create WLM workload group
260+
run: |
261+
curl -ksu admin:"${OPENSEARCH_INITIAL_ADMIN_PASSWORD}" \
262+
-H 'Content-Type: application/json' \
263+
-X PUT 'https://localhost:9200/_wlm/workload_group' \
264+
-d '{"name":"test_group","resiliency_mode":"soft","resource_limits":{"cpu":0.1,"memory":0.1}}'
265+
266+
- name: Cypress tests
267+
uses: cypress-io/github-action@v5
268+
with:
269+
working-directory: OpenSearch-Dashboards/plugins/query-insights-dashboards
270+
command: yarn run cypress run --config defaultCommandTimeout=120000,requestTimeout=120000,responseTimeout=120000,pageLoadTimeout=180000,taskTimeout=120000,execTimeout=120000,excludeSpecPattern=cypress/e2e/qi/**/*
271+
browser: chrome
272+
env:
273+
CYPRESS_CACHE_FOLDER: ${{ matrix.cypress_cache_folder }}
274+
CI: true
275+
timeout-minutes: 120
276+
277+
- uses: actions/upload-artifact@v4
278+
if: failure()
279+
with:
280+
name: cypress-screenshots-${{ matrix.os }}
281+
path: OpenSearch-Dashboards/plugins/query-insights-dashboards/cypress/screenshots
282+
283+
- uses: actions/upload-artifact@v4
284+
if: always()
285+
with:
286+
name: cypress-videos-${{ matrix.os }}
287+
path: OpenSearch-Dashboards/plugins/query-insights-dashboards/cypress/videos

.github/workflows/cypress-tests.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ jobs:
9090
find OpenSearch/modules/autotagging-commons/build/distributions/ -name "*.zip" -exec cp {} query-insights/plugins/ \;
9191
find OpenSearch/plugins/workload-management/build/distributions/ -name "*.zip" -exec cp {} query-insights/plugins/ \;
9292
93-
# List copied plugins
93+
# List copied plugin
9494
echo "Contents of plugins directory:"
9595
ls -la query-insights/plugins/
9696
@@ -288,7 +288,7 @@ jobs:
288288
uses: cypress-io/github-action@v5
289289
with:
290290
working-directory: OpenSearch-Dashboards/plugins/query-insights-dashboards
291-
command: yarn run cypress run --config defaultCommandTimeout=120000,requestTimeout=120000,responseTimeout=120000,pageLoadTimeout=180000,taskTimeout=120000,execTimeout=120000
291+
command: yarn run cypress run --config defaultCommandTimeout=120000,requestTimeout=120000,responseTimeout=120000,pageLoadTimeout=180000,taskTimeout=120000,execTimeout=120000,excludeSpecPattern=cypress/e2e/wlm/**/*
292292
wait-on: 'http://localhost:5601'
293293
wait-on-timeout: 1200
294294
browser: chrome

0 commit comments

Comments
 (0)