Skip to content

Commit 94252cc

Browse files
gkechhors
andauthored
K8SPG-719 PMM3 support (#1084)
* K8SPG-719 * fix reviewdog * e2e test for pmm3 * run shfmt and introduce make command * handle nil secret & add unit test case * cr: remove pmm server helm version in order to always use the latest always * Revert "run shfmt and introduce make command" This reverts commit 897e1c8. * changes on functions after revert * add empty lines * cr: specify in the log PMM3 is used with token and PMM2 with api key --------- Co-authored-by: Viacheslav Sarzhan <[email protected]>
1 parent afc1f88 commit 94252cc

23 files changed

+1109
-13
lines changed

deploy/secrets.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ metadata:
55
type: Opaque
66
stringData:
77
PMM_SERVER_KEY: ""
8+
#PMM_SERVER_TOKEN: ""
89
---
910
apiVersion: v1
1011
kind: Secret

e2e-tests/functions

+128-2
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,41 @@ deploy_pmm_server() {
365365
fi
366366
}
367367

368+
deploy_pmm3_server() {
369+
helm uninstall -n "${NAMESPACE}" pmm || :
370+
if [[ $OPENSHIFT ]]; then
371+
platform=openshift
372+
oc create sa pmm-server -n "$NAMESPACE"
373+
oc adm policy add-scc-to-user privileged -z pmm-server -n "$NAMESPACE"
374+
375+
if [[ $OPERATOR_NS ]]; then
376+
timeout 30 oc delete clusterrolebinding $(kubectl get clusterrolebinding | grep 'pmm-pg-operator-' | awk '{print $1}') || :
377+
oc create clusterrolebinding pmm-pg-operator-cluster-wide --clusterrole=percona-postgresql-operator --serviceaccount=$NAMESPACE:pmm-server -n "$NAMESPACE"
378+
oc patch clusterrole/percona-postgresql-operator --type json -p='[{"op":"add","path": "/rules/-","value":{"apiGroups":["security.openshift.io"],"resources":["securitycontextconstraints"],"verbs":["use"],"resourceNames":["privileged"]}}]' ${OPERATOR_NS:+-n $OPERATOR_NS}
379+
else
380+
oc create rolebinding pmm-pg-operator-namespace-only --role percona-postgresql-operator --serviceaccount=$NAMESPACE:pmm-server -n "${NAMESPACE}"
381+
oc patch role/percona-postgresql-operator --type json -p='[{"op":"add","path": "/rules/-","value":{"apiGroups":["security.openshift.io"],"resources":["securitycontextconstraints"],"verbs":["use"],"resourceNames":["privileged"]}}]' -n "$NAMESPACE"
382+
fi
383+
helm install monitoring --set imageTag=${IMAGE_PMM3_SERVER#*:} --set imageRepo=${IMAGE_PMM3_SERVER%:*} --set platform=$platform --set sa=pmm-server --set supresshttp2=false https://percona-charts.storage.googleapis.com/pmm-server-${PMM3_SERVER_VERSION}.tgz -n "$NAMESPACE"
384+
else
385+
platform=kubernetes
386+
387+
helm uninstall -n "${NAMESPACE}" monitoring || :
388+
helm repo remove percona || :
389+
kubectl delete clusterrole monitoring --ignore-not-found
390+
kubectl delete clusterrolebinding monitoring --ignore-not-found
391+
392+
helm repo add percona https://percona.github.io/percona-helm-charts/
393+
helm install monitoring percona/pmm -n "${NAMESPACE}" \
394+
--set fullnameOverride=monitoring \
395+
--set imageTag=3-dev-latest \
396+
--set imageRepo=perconalab/pmm-server \
397+
--set service.type=LoadBalancer \
398+
--set platform="$platform" \
399+
--force
400+
fi
401+
}
402+
368403
generate_pmm_api_key() {
369404
local ADMIN_PASSWORD=$(kubectl -n "${NAMESPACE}" exec monitoring-0 -- bash -c "printenv | grep ADMIN_PASSWORD | cut -d '=' -f2")
370405
local PMM_SERVICE_IP=$(get_service_ip monitoring-service)
@@ -378,17 +413,71 @@ generate_pmm_api_key() {
378413
| jq -r .key
379414
}
380415

416+
generate_pmm3_server_token() {
417+
local key_name=$RANDOM
418+
419+
local ADMIN_PASSWORD
420+
ADMIN_PASSWORD=$(kubectl -n "${NAMESPACE}" get secret pmm-secret -o jsonpath="{.data.PMM_ADMIN_PASSWORD}" | base64 --decode)
421+
422+
if [[ -z $ADMIN_PASSWORD ]]; then
423+
echo "Error: ADMIN_PASSWORD is empty or not found!" >&2
424+
return 1
425+
fi
426+
427+
local create_response create_status_code create_json_response
428+
create_response=$(curl --insecure -s -X POST -H 'Content-Type: application/json' -H 'Accept: application/json' \
429+
-d "{\"name\":\"${key_name}\", \"role\":\"Admin\", \"isDisabled\":false}" \
430+
--user "admin:${ADMIN_PASSWORD}" \
431+
"https://$(get_service_ip monitoring-service)/graph/api/serviceaccounts" \
432+
-w "\n%{http_code}")
433+
434+
create_status_code=$(echo "$create_response" | tail -n1)
435+
create_json_response=$(echo "$create_response" | sed '$ d')
436+
437+
if [[ $create_status_code -ne 201 ]]; then
438+
echo "Error: Failed to create PMM service account. HTTP Status: $create_status_code" >&2
439+
echo "Response: $create_json_response" >&2
440+
return 1
441+
fi
442+
443+
local service_account_id
444+
service_account_id=$(echo "$create_json_response" | jq -r '.id')
445+
446+
if [[ -z $service_account_id || $service_account_id == "null" ]]; then
447+
echo "Error: Failed to extract service account ID!" >&2
448+
return 1
449+
fi
450+
451+
local token_response token_status_code token_json_response
452+
token_response=$(curl --insecure -s -X POST -H 'Content-Type: application/json' \
453+
-d "{\"name\":\"${key_name}\"}" \
454+
--user "admin:${ADMIN_PASSWORD}" \
455+
"https://$(get_service_ip monitoring-service)/graph/api/serviceaccounts/${service_account_id}/tokens" \
456+
-w "\n%{http_code}")
457+
458+
token_status_code=$(echo "$token_response" | tail -n1)
459+
token_json_response=$(echo "$token_response" | sed '$ d')
460+
461+
if [[ $token_status_code -ne 200 ]]; then
462+
echo "Error: Failed to create token. HTTP Status: $token_status_code" >&2
463+
echo "Response: $token_json_response" >&2
464+
return 1
465+
fi
466+
467+
echo "$token_json_response" | jq -r '.key'
468+
}
469+
381470
get_metric_values() {
382471
local metric=$1
383472
local instance=$2
384-
local api_key=$3
473+
local token=$3
385474
local start=$($date -u "+%s" -d "-5 minute")
386475
local end=$($date -u "+%s")
387476
local endpoint=$(get_service_ip monitoring-service)
388477

389478
local wait_count=20
390479
local retry=0
391-
until [[ $(curl -s -k -H "Authorization: Bearer ${api_key}" "https://$endpoint/graph/api/datasources/proxy/1/api/v1/query_range?query=min%28$metric%7Bnode_name%3D%7E%22$instance%22%7d%20or%20$metric%7Bnode_name%3D%7E%22$instance%22%7D%29&start=$start&end=$end&step=60" \
480+
until [[ $(curl -s -k -H "Authorization: Bearer ${token}" "https://$endpoint/graph/api/datasources/proxy/1/api/v1/query_range?query=min%28$metric%7Bnode_name%3D%7E%22$instance%22%7d%20or%20$metric%7Bnode_name%3D%7E%22$instance%22%7D%29&start=$start&end=$end&step=60" \
392481
| jq '.data.result[0].values[][1]' \
393482
| grep '^"[0-9]') ]]; do
394483
sleep 2
@@ -438,6 +527,43 @@ EOF
438527
rm -f payload.json
439528
}
440529

530+
get_qan20_values_pmm3() {
531+
local instance=$1
532+
local token=$2
533+
local start=$($date -u "+%Y-%m-%dT%H:%M:%S" -d "-30 minute")
534+
local end=$($date -u "+%Y-%m-%dT%H:%M:%S")
535+
local endpoint=$(get_service_ip monitoring-service)
536+
537+
cat >payload.json <<EOF
538+
{
539+
"columns":[
540+
"load",
541+
"num_queries",
542+
"query_time"
543+
],
544+
"first_seen": false,
545+
"group_by": "queryid",
546+
"include_only_fields": [],
547+
"keyword": "",
548+
"labels": [
549+
{
550+
"key": "cluster",
551+
"value": ["postgresql"]
552+
}],
553+
"limit": 10,
554+
"offset": 0,
555+
"order_by": "-load",
556+
"main_metric": "load",
557+
"period_start_from": "$($date -u -d '-12 hour' '+%Y-%m-%dT%H:%M:%S%:z')",
558+
"period_start_to": "$($date -u '+%Y-%m-%dT%H:%M:%S%:z')"
559+
}
560+
EOF
561+
562+
curl -s -k -H "Authorization: Bearer ${token}" -XPOST -d @payload.json "https://$endpoint/v1/qan/metrics:getReport" \
563+
| jq '.rows[].sparkline'
564+
rm -f payload.json
565+
}
566+
441567
deploy_chaos_mesh() {
442568
destroy_chaos_mesh
443569

e2e-tests/run-pr.csv

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ demand-backup
44
finalizers
55
init-deploy
66
monitoring
7+
monitoring-pmm3
78
one-pod
89
operator-self-healing
910
pitr

e2e-tests/run-release.csv

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ init-deploy
66
major-upgrade
77
migration-backup-s3
88
monitoring
9+
monitoring-pmm3
910
one-pod
1011
operator-self-healing
1112
pitr
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
apiVersion: kuttl.dev/v1beta1
2+
kind: TestAssert
3+
timeout: 120
4+
---
5+
apiVersion: apiextensions.k8s.io/v1
6+
kind: CustomResourceDefinition
7+
metadata:
8+
name: perconapgclusters.pgv2.percona.com
9+
spec:
10+
group: pgv2.percona.com
11+
names:
12+
kind: PerconaPGCluster
13+
listKind: PerconaPGClusterList
14+
plural: perconapgclusters
15+
singular: perconapgcluster
16+
scope: Namespaced
17+
---
18+
apiVersion: kuttl.dev/v1beta1
19+
kind: TestAssert
20+
metadata:
21+
name: check-operator-deploy-status
22+
timeout: 120
23+
commands:
24+
- script: kubectl assert exist-enhanced deployment percona-postgresql-operator -n ${OPERATOR_NS:-$NAMESPACE} --field-selector status.readyReplicas=1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
apiVersion: kuttl.dev/v1beta1
2+
kind: TestStep
3+
timeout: 10
4+
commands:
5+
- script: |-
6+
set -o errexit
7+
set -o xtrace
8+
9+
source ../../functions
10+
init_temp_dir # do this only in the first TestStep
11+
12+
deploy_operator
13+
deploy_client
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
apiVersion: kuttl.dev/v1beta1
2+
kind: TestAssert
3+
timeout: 520
4+
---
5+
apiVersion: apps/v1
6+
kind: StatefulSet
7+
metadata:
8+
name: monitoring
9+
status:
10+
collisionCount: 0
11+
currentReplicas: 1
12+
observedGeneration: 1
13+
readyReplicas: 1
14+
replicas: 1
15+
updatedReplicas: 1
16+
---
17+
kind: Service
18+
apiVersion: v1
19+
metadata:
20+
name: monitoring-service
21+
---
22+
apiVersion: v1
23+
count: 1
24+
involvedObject:
25+
apiVersion: v1
26+
kind: Service
27+
name: monitoring-service
28+
kind: Event
29+
message: Ensured load balancer
30+
reason: EnsuredLoadBalancer
31+
source:
32+
component: service-controller
33+
type: Normal
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
apiVersion: kuttl.dev/v1beta1
2+
kind: TestStep
3+
commands:
4+
- script: |-
5+
set -o errexit
6+
set -o xtrace
7+
8+
source ../../functions
9+
10+
deploy_pmm3_server
11+
timeout: 300
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
apiVersion: kuttl.dev/v1beta1
2+
kind: TestAssert
3+
---
4+
apiVersion: v1
5+
kind: Secret
6+
type: Opaque
7+
metadata:
8+
name: monitoring-pmm3-pmm-secret
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
apiVersion: kuttl.dev/v1beta1
2+
kind: TestStep
3+
commands:
4+
- script: |-
5+
set -o errexit
6+
set -o xtrace
7+
8+
source ../../functions
9+
kubectl create -n "${NAMESPACE}" secret generic monitoring-pmm3-pmm-secret --from-literal=PMM_SERVER_TOKEN="" || true
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
apiVersion: kuttl.dev/v1beta1
2+
kind: TestAssert
3+
timeout: 420
4+
---
5+
apiVersion: pgv2.percona.com/v2
6+
kind: PerconaPGCluster
7+
metadata:
8+
labels:
9+
e2e: monitoring-pmm3
10+
name: monitoring-pmm3
11+
spec:
12+
backups:
13+
pgbackrest:
14+
manual:
15+
options:
16+
- --type=full
17+
repoName: repo1
18+
repos:
19+
- name: repo1
20+
schedules:
21+
full: 0 0 * * 6
22+
volume:
23+
volumeClaimSpec:
24+
accessModes:
25+
- ReadWriteOnce
26+
resources:
27+
requests:
28+
storage: 1Gi
29+
instances:
30+
- dataVolumeClaimSpec:
31+
accessModes:
32+
- ReadWriteOnce
33+
resources:
34+
requests:
35+
storage: 1Gi
36+
name: instance1
37+
replicas: 3
38+
pmm:
39+
enabled: true
40+
secret: monitoring-pmm3-pmm-secret
41+
serverHost: monitoring-service
42+
port: 5432
43+
proxy:
44+
pgBouncer:
45+
port: 5432
46+
replicas: 3
47+
status:
48+
pgbouncer:
49+
ready: 3
50+
size: 3
51+
postgres:
52+
instances:
53+
- name: instance1
54+
ready: 3
55+
size: 3
56+
ready: 3
57+
size: 3
58+
state: ready
59+
---
60+
kind: Job
61+
apiVersion: batch/v1
62+
metadata:
63+
labels:
64+
postgres-operator.crunchydata.com/cluster: monitoring-pmm3
65+
postgres-operator.crunchydata.com/pgbackrest: ''
66+
postgres-operator.crunchydata.com/pgbackrest-backup: replica-create
67+
postgres-operator.crunchydata.com/pgbackrest-repo: repo1
68+
ownerReferences:
69+
- apiVersion: pgv2.percona.com/v2
70+
kind: PerconaPGBackup
71+
controller: true
72+
blockOwnerDeletion: true
73+
status:
74+
succeeded: 1
75+
---
76+
apiVersion: pgv2.percona.com/v2
77+
kind: PerconaPGBackup
78+
metadata:
79+
annotations:
80+
pgv2.percona.com/pgbackrest-backup-job-type: replica-create
81+
generation: 1
82+
spec:
83+
pgCluster: monitoring-pmm3
84+
repoName: repo1
85+
status:
86+
backupType: full
87+
repo:
88+
name: repo1
89+
schedules:
90+
full: 0 0 * * 6
91+
volume:
92+
volumeClaimSpec:
93+
accessModes:
94+
- ReadWriteOnce
95+
resources:
96+
requests:
97+
storage: 1Gi
98+
state: Succeeded
99+
storageType: filesystem

0 commit comments

Comments
 (0)