タグを一つ足すためにファイルを直した
한국어 원문으로 표시합니다.
목표
대시보드의 버전과 저장 메시지를 읽고, 두 판의 차이를 사람이 읽을 수 있게 뽑고, 데이터소스를 변수로 빼 옮길 수 있게 만든 뒤, 파일이 원본이 되게 바꾸고 파일과 화면이 같은지 스스로 검사하는 도구까지 만듭니다.
왜 중요한가
대시보드를 저장소에 넣어 두기만 하면 반년 뒤에 화면과 파일이 완전히 달라져 있다. 아무도 파일을 고칠 이유가 없고 화면에서 고치는 것을 막는 것도 없기 때문이다. 파일에서 제공되게 만들면 그때부터 화면 저장이 막히고, 대시보드를 바꾸는 유일한 길이 파일이 된다 — 불편해 보이는 그 제약이 화면과 파일이 갈라질 길을 없앤다. 그리고 버전이 남아 있다는 사실과 무엇이 바뀌었는지 안다는 사실은 다르다. 저장할 때마다 바뀌는 필드를 걷어 내지 않으면 diff 는 통째로 빨개져서 아무것도 알려 주지 않는다.
단계
lab-start-grafana로 Grafana 를 띄우고/opt/lab/gfd/gfd-as-code/start.json를 올리세요(uidgfd-code). 그 다음 1번 패널의 제목을지금 요청률로 바꾸고, 저장 메시지를 10자 이상 붙여 다시 저장하세요.http://127.0.0.1:3000/api/dashboards/uid/gfd-code/versions를 받아/root/gfd-as-code/02-versions.txt에 세 줄을 적으세요.latest=최신 버전 번호,message=그 버전의 저장 메시지,first_message=버전 1 의 저장 메시지입니다. 세 값 모두 응답에 적힌 그대로 옮겨 적습니다./root/gfd-as-code/normalize.py를 만드세요. 대시보드 JSON 파일 경로를 인자로 받아 대시보드 본문만({"dashboard": ...}로 감싸여 있으면 벗겨서) 남기고, 최상위의version·id·iteration을 걷어 내고, 키를 정렬해 표준출력으로 내놓아야 합니다. 패널의id는 남깁니다./root/gfd-as-code/diff.sh를 만드세요. 버전 번호 둘을 인자로 받아 두 버전을 정규화한 뒤 견주고, 같으면 아무것도 출력하지 않고 0 으로, 다르면 차이를 출력하고 0 이 아닌 값으로 끝나야 합니다. 그리고bash /root/gfd-as-code/diff.sh 1 2의 결과를 보고/root/gfd-as-code/04-diff.txt의changed=줄에 어느 패널의 무엇이 어떻게 바뀌었는지 20자 이상으로 적으세요.- 없는 데이터소스 uid 로 질의를 던져 보고 돌아오는 HTTP 코드를, 그리고 이 파드의 실제 prometheus 데이터소스 uid 를
/root/gfd-as-code/05-uid.txt에missing_status=와ds_uid=두 줄로 적으세요. 그 다음DS라는 이름의datasource타입 템플릿 변수(대상은prometheus)를 만들고, 두 패널이 모두 그 변수(${DS})를 가리키게 바꿔 저장하세요. - 지금 대시보드를 정규화해
/root/gfd-as-code/dash/gfd-code.json에 저장하고,/root/gfd-as-code/provisioning/dashboards/lab.yml에 그 폴더를 읽는 프로비저닝 설정을 쓴 뒤, Grafana 를GF_PATHS_PROVISIONING=/root/gfd-as-code/provisioning으로 다시 띄우세요. 대시보드가 파일에서 오게 되면 조회 응답의meta.provisioned가 참이 됩니다. - 지금 대시보드를 그대로 다시 저장해 보고, 돌아오는 HTTP 코드와 응답 본문의
message를/root/gfd-as-code/07-blocked.txt에status=와message=로 적으세요. 그리고procedure=줄에 앞으로 이 대시보드를 바꾸려면 무엇을 고치고 무엇을 다시 해야 하는지 40자 이상으로 적으세요. - 대시보드에
gitops태그를 붙이세요. 단 파일을 고쳐서 해야 합니다. 그리고/root/gfd-as-code/verify.sh를 만드세요 — 대시보드 JSON 파일 경로를 인자로 받아(기본값/root/gfd-as-code/dash/gfd-code.json) 그 파일과 지금 화면을 정규화해 견주고, 같으면 0, 다르면 0 이 아닌 값으로 끝나야 합니다. 마지막으로/root/gfd-as-code/08-bundle.md에files=(저장소에 올릴 파일 목록)와revert=(되돌리는 방법, 40자 이상) 두 줄을 적으세요.
참고
- Grafana 는
lab-start-grafana로 켭니다. 6단계부터는 프로비저닝 경로를 바꿔 직접 다시 띄웁니다. - 시작 대시보드는
/opt/lab/gfd/gfd-as-code/start.json에 있습니다. 읽기만 하세요 — 8단계에서 반례로 다시 씁니다. - 버전 목록 응답의 각 항목에는 그 버전의 본문이
data에 함께 들어 있습니다. - 프로비저닝 설정은 기동할 때 한 번만 읽습니다. 파일을 고쳤는데 화면이 그대로면 다시 띄우지 않은 것입니다.
- 흔한 실수 ① 다시 띄울 때
GF_PATHS_DATA를 빼먹는 것. 버전 이력이 통째로 사라집니다. - 흔한 실수 ② 화면에서 고치고 파일을 안 고치는 것. 6단계 뒤에는 화면 저장이 막히므로 바로 드러납니다.
- 프로비저닝 · 대시보드 JSON 모델 · 대시보드 HTTP API · 변수
저장 메시지 없이 바꾸면 아무것도 남지 않는다
lab-start-grafana 로 Grafana 를 띄우고 /opt/lab/gfd/gfd-as-code/start.json 를 올리세요(uid gfd-code). 그 다음 1번 패널의 제목을 지금 요청률 로 바꾸고, 저장 메시지를 10자 이상 붙여 다시 저장하세요.
저장 API 본문은 {"dashboard": ..., "overwrite": true, "message": "..."} 입니다. 메시지를 빼면 버전 목록에 시각만 남습니다 — 반년 뒤에 이 버전으로 되돌릴지 판단할 근거가 없어지는 것입니다.
버전 목록이 실제로 남기는 것
http://127.0.0.1:3000/api/dashboards/uid/gfd-code/versions 를 받아 /root/gfd-as-code/02-versions.txt 에 세 줄을 적으세요. latest= 최신 버전 번호, message= 그 버전의 저장 메시지, first_message= 버전 1 의 저장 메시지입니다. 세 값 모두 응답에 적힌 그대로 옮겨 적습니다.
버전 1 의 메시지를 보고 놀랄 수 있습니다 — 직접 적어 보낸 것과 다릅니다. 그것이 이 단계에서 확인할 사실입니다. jq 로 max_by(.version) 과 select(.version == 1) 을 각각 뽑으면 됩니다.
두 판을 견줄 수 있게 만든다
/root/gfd-as-code/normalize.py 를 만드세요. 대시보드 JSON 파일 경로를 인자로 받아 대시보드 본문만({"dashboard": ...} 로 감싸여 있으면 벗겨서) 남기고, 최상위의 version·id·iteration 을 걷어 내고, 키를 정렬해 표준출력으로 내놓아야 합니다. 패널의 id 는 남깁니다.
저장할 때마다 바뀌는 필드가 섞여 있으면 diff 가 통째로 빨개집니다. 같은 입력에 늘 같은 출력이 나와야 하므로 키 순서를 고정하세요. 파이썬의 json.dumps 에는 그 옵션이 있습니다.
무엇이 바뀌었나 — 양방향으로 도는 도구
/root/gfd-as-code/diff.sh 를 만드세요. 버전 번호 둘을 인자로 받아 두 버전을 정규화한 뒤 견주고, 같으면 아무것도 출력하지 않고 0 으로, 다르면 차이를 출력하고 0 이 아닌 값으로 끝나야 합니다. 그리고 bash /root/gfd-as-code/diff.sh 1 2 의 결과를 보고 /root/gfd-as-code/04-diff.txt 의 changed= 줄에 어느 패널의 무엇이 어떻게 바뀌었는지 20자 이상으로 적으세요.
버전별 본문은 버전 목록 응답의 data 에 들어 있습니다. diff 명령은 차이가 있으면 1 로 끝나므로, 그 종료 코드를 그대로 쓰면 됩니다. 같은 버전 둘을 주었을 때도 동작하는지 꼭 시험해 보세요 — 한쪽만 되는 도구는 '차이가 없다' 와 '도구가 고장 났다' 를 구별해 주지 못합니다.
옮기면 패널이 비는 이유
없는 데이터소스 uid 로 질의를 던져 보고 돌아오는 HTTP 코드를, 그리고 이 파드의 실제 prometheus 데이터소스 uid 를 /root/gfd-as-code/05-uid.txt 에 missing_status= 와 ds_uid= 두 줄로 적으세요. 그 다음 DS 라는 이름의 datasource 타입 템플릿 변수(대상은 prometheus)를 만들고, 두 패널이 모두 그 변수(${DS})를 가리키게 바꿔 저장하세요.
데이터소스 프록시 경로는 /api/datasources/proxy/uid/<uid>/api/v1/query 입니다. 없는 uid 를 넣어도 화면에는 오류가 아니라 빈 그래프로 보입니다 — 그래서 옮겼을 때 원인을 찾기 어렵습니다. 변수는 templating.list 에 넣고, 패널의 datasource.uid 를 변수 참조 문자열로 바꿉니다.
파일이 원본이 되게 한다
지금 대시보드를 정규화해 /root/gfd-as-code/dash/gfd-code.json 에 저장하고, /root/gfd-as-code/provisioning/dashboards/lab.yml 에 그 폴더를 읽는 프로비저닝 설정을 쓴 뒤, Grafana 를 GF_PATHS_PROVISIONING=/root/gfd-as-code/provisioning 으로 다시 띄우세요. 대시보드가 파일에서 오게 되면 조회 응답의 meta.provisioned 가 참이 됩니다.
프로비저닝 설정은 Grafana 가 기동할 때 한 번만 읽습니다 — 파일만 써 두고 다시 띄우지 않으면 아무 일도 일어나지 않습니다. 설정에는 apiVersion·providers 가 들어가고 options.path 가 대시보드 JSON 이 든 폴더를 가리킵니다. 다시 띄울 때 데이터 폴더(GF_PATHS_DATA)는 그대로 두어야 버전 이력이 남습니다.
이제 화면에서는 저장할 수 없다
지금 대시보드를 그대로 다시 저장해 보고, 돌아오는 HTTP 코드와 응답 본문의 message 를 /root/gfd-as-code/07-blocked.txt 에 status= 와 message= 로 적으세요. 그리고 procedure= 줄에 앞으로 이 대시보드를 바꾸려면 무엇을 고치고 무엇을 다시 해야 하는지 40자 이상으로 적으세요.
거절되는 요청이라 아무것도 바뀌지 않습니다. 마음 놓고 던져 보세요. 응답 코드는 curl -w '%{http_code}' 로 받을 수 있습니다. 불편해 보이는 이 제약이 바로 화면과 파일이 갈라지지 않게 하는 장치입니다.
응용 — 파일을 고쳐 화면을 바꾸고 둘이 같은지 검사한다
대시보드에 gitops 태그를 붙이세요. 단 파일을 고쳐서 해야 합니다. 그리고 /root/gfd-as-code/verify.sh 를 만드세요 — 대시보드 JSON 파일 경로를 인자로 받아(기본값 /root/gfd-as-code/dash/gfd-code.json) 그 파일과 지금 화면을 정규화해 견주고, 같으면 0, 다르면 0 이 아닌 값으로 끝나야 합니다. 마지막으로 /root/gfd-as-code/08-bundle.md 에 files= (저장소에 올릴 파일 목록)와 revert= (되돌리는 방법, 40자 이상) 두 줄을 적으세요.
파일을 고친 뒤에는 Grafana 를 다시 읽히게 해야 화면에 반영됩니다(앞 단계에서 한 것과 같습니다). 검사기는 양방향으로 시험해 보세요 — 저장소 사본을 주면 통과하고, 다른 대시보드 파일(예: /opt/lab/gfd/gfd-as-code/start.json)을 주면 떨어져야 합니다. 무엇을 주어도 통과하는 검사기는 없는 것보다 나쁩니다.