0 added
0 removed
Original
2026-01-01
Modified
2026-03-10
1
<p>Теги: gitlab, harbor, snyk, pages, merge request</p>
1
<p>Теги: gitlab, harbor, snyk, pages, merge request</p>
2
<p>В<a>предыдущем посте</a>я рассказал, как развернуть Harbor - репозиторий для хранения докер образов со встроенной проверкой на уязвимости (Clair). Логично собрать конвейер, который при получении очередного пуша в feature branch производит все необходимые проверки и выдаёт отчёт. Так и сделаем: - push to feature-branch - сборка контейнера - анализ кода в собранном контейнере на уязвимости (<a>SNYK</a>) - push образа в харбор - скан образа на уязвимости (harbor умеет делать автоматически, либо через API) - получение ссылки на отчеты по обоим проверкам в окне merge request</p>
2
<p>В<a>предыдущем посте</a>я рассказал, как развернуть Harbor - репозиторий для хранения докер образов со встроенной проверкой на уязвимости (Clair). Логично собрать конвейер, который при получении очередного пуша в feature branch производит все необходимые проверки и выдаёт отчёт. Так и сделаем: - push to feature-branch - сборка контейнера - анализ кода в собранном контейнере на уязвимости (<a>SNYK</a>) - push образа в харбор - скан образа на уязвимости (harbor умеет делать автоматически, либо через API) - получение ссылки на отчеты по обоим проверкам в окне merge request</p>
3
<p>В settings гитлаба можно настроить переменные для репозитория, чтобы не прописывать credentials в открытом виде. В приложенном пайплайне предполагается, что используется runner с тэгом harbor. Пайплайн предполагает запуск docker-in-docker с проброшенным с хоста сокетом.</p>
3
<p>В settings гитлаба можно настроить переменные для репозитория, чтобы не прописывать credentials в открытом виде. В приложенном пайплайне предполагается, что используется runner с тэгом harbor. Пайплайн предполагает запуск docker-in-docker с проброшенным с хоста сокетом.</p>
4
image: $harbor_registry/library/docker:latest variables: DOCKER_DRIVER: overlay2 GIT_SUBMODULE_STRATEGY: recursive SCAN_API: https://$harbor_registry/api/repositories/repo%2Fproject/tags/$CI_COMMIT_SHORT_SHA/scan CVE_API: https://$harbor_registry/api/repositories/repo%2Fproject/tags/$CI_COMMIT_SHORT_SHA/vulnerability/details CVE_URI: https://$harbor_registry/harbor/projects/3/repositories/repo%2Fproject/tags/${CI_COMMIT_SHORT_SHA} JSON_TYPE: 'Accept: application/json' JSON_CONTENT: 'Content-Type: application/json' AUTH: $harbor_auth SNYK_TOKEN: $snyk_token SHARED_PATH: /builds/$CI_PROJECT_PATH/artifacts stages: - build - snyk - deploy - pages build_docker: before_script: - docker login -u $harbor_login -p $harbor_password https://$harbor_registry stage: build tags: - harbor script: - docker build -t $harbor_registry/repo/project:$CI_COMMIT_SHORT_SHA . only: - /^feature-.*$/ pages: stage: pages script: - mkdir public - | echo " <html> <title> CVE Reports for project ${CI_PROJECT_NAME}</title> <body> <ul> <li><a href=./snyk.html>SNYK report</a></li> <li><a href=${CVE_URI}>Harbor CVE report</a></li> </ul> </body> </html> " > public/index.html - cp artifacts/snyk.html public/ tags: - harbor artifacts: paths: - public snyk_code: stage: snyk tags: - harbor script: - mkdir -p ${SHARED_PATH} - | echo " if [ -f /usr/bin/yum ];then yum install npm -y;fi npm install -g snyk npm install -g snyk-to-html snyk auth $SNYK_TOKEN snyk test --json | snyk-to-html -o /snyk.html " > snyk.sh - docker create --name snyk --entrypoint bash $harbor_registry/repo/project:$CI_COMMIT_SHORT_SHA /snyk.sh - docker cp snyk.sh snyk:/snyk.sh - docker start snyk - docker wait snyk - docker cp snyk:/snyk.html ${SHARED_PATH}/snyk.html - docker rm snyk allow_failure: true artifacts: paths: - ${SHARED_PATH}/snyk.html only: - /^feature-.*$/ push_docker_to_harbor: before_script: - docker login -u $harbor_login -p $harbor_password https://$harbor_registry stage: deploy tags: - harbor script: - docker push $harbor_registry/repo/project:$CI_COMMIT_SHORT_SHA - curl -I -k -H "$JSON_TYPE" -H "$JSON_CONTENT" -H "$AUTH" -X POST $SCAN_API allow_failure: true only: - /^feature-.*$/<h2>Немного пояснений</h2>
4
image: $harbor_registry/library/docker:latest variables: DOCKER_DRIVER: overlay2 GIT_SUBMODULE_STRATEGY: recursive SCAN_API: https://$harbor_registry/api/repositories/repo%2Fproject/tags/$CI_COMMIT_SHORT_SHA/scan CVE_API: https://$harbor_registry/api/repositories/repo%2Fproject/tags/$CI_COMMIT_SHORT_SHA/vulnerability/details CVE_URI: https://$harbor_registry/harbor/projects/3/repositories/repo%2Fproject/tags/${CI_COMMIT_SHORT_SHA} JSON_TYPE: 'Accept: application/json' JSON_CONTENT: 'Content-Type: application/json' AUTH: $harbor_auth SNYK_TOKEN: $snyk_token SHARED_PATH: /builds/$CI_PROJECT_PATH/artifacts stages: - build - snyk - deploy - pages build_docker: before_script: - docker login -u $harbor_login -p $harbor_password https://$harbor_registry stage: build tags: - harbor script: - docker build -t $harbor_registry/repo/project:$CI_COMMIT_SHORT_SHA . only: - /^feature-.*$/ pages: stage: pages script: - mkdir public - | echo " <html> <title> CVE Reports for project ${CI_PROJECT_NAME}</title> <body> <ul> <li><a href=./snyk.html>SNYK report</a></li> <li><a href=${CVE_URI}>Harbor CVE report</a></li> </ul> </body> </html> " > public/index.html - cp artifacts/snyk.html public/ tags: - harbor artifacts: paths: - public snyk_code: stage: snyk tags: - harbor script: - mkdir -p ${SHARED_PATH} - | echo " if [ -f /usr/bin/yum ];then yum install npm -y;fi npm install -g snyk npm install -g snyk-to-html snyk auth $SNYK_TOKEN snyk test --json | snyk-to-html -o /snyk.html " > snyk.sh - docker create --name snyk --entrypoint bash $harbor_registry/repo/project:$CI_COMMIT_SHORT_SHA /snyk.sh - docker cp snyk.sh snyk:/snyk.sh - docker start snyk - docker wait snyk - docker cp snyk:/snyk.html ${SHARED_PATH}/snyk.html - docker rm snyk allow_failure: true artifacts: paths: - ${SHARED_PATH}/snyk.html only: - /^feature-.*$/ push_docker_to_harbor: before_script: - docker login -u $harbor_login -p $harbor_password https://$harbor_registry stage: deploy tags: - harbor script: - docker push $harbor_registry/repo/project:$CI_COMMIT_SHORT_SHA - curl -I -k -H "$JSON_TYPE" -H "$JSON_CONTENT" -H "$AUTH" -X POST $SCAN_API allow_failure: true only: - /^feature-.*$/<h2>Немного пояснений</h2>
5
<p>Пайплайн разделён на 4 стэйджа: build - сборка образа snyk - проверка сныком deploy - отправка в харбор и скан образа pages - выкладка артифактов в gitlab pages</p>
5
<p>Пайплайн разделён на 4 стэйджа: build - сборка образа snyk - проверка сныком deploy - отправка в харбор и скан образа pages - выкладка артифактов в gitlab pages</p>
6
<h4>stage SNYK</h4>
6
<h4>stage SNYK</h4>
7
<ul><li>создаётся скрипт snyk.sh, который устанавливает SNYK и запускает проверку</li>
7
<ul><li>создаётся скрипт snyk.sh, который устанавливает SNYK и запускает проверку</li>
8
<li>запускается контейнер на основе ранее собранного образа</li>
8
<li>запускается контейнер на основе ранее собранного образа</li>
9
<li>туда копируется созданный скрипт</li>
9
<li>туда копируется созданный скрипт</li>
10
<li>запускается скрипт</li>
10
<li>запускается скрипт</li>
11
<li>из контейнера забирается отчёт и помещается в артифакты (чтобы вытащить артифакт в другом стэйдже: pages)</li>
11
<li>из контейнера забирается отчёт и помещается в артифакты (чтобы вытащить артифакт в другом стэйдже: pages)</li>
12
</ul><p>### stage deploy - пушим образ в harbor репозиторий - запускаем скан через API</p>
12
</ul><p>### stage deploy - пушим образ в harbor репозиторий - запускаем скан через API</p>
13
<h4>stage pages</h4>
13
<h4>stage pages</h4>
14
<ul><li>формируем индексную страницу с ссылками на образ в харборе (со всеми проверками) и отчёт от snyk</li>
14
<ul><li>формируем индексную страницу с ссылками на образ в харборе (со всеми проверками) и отчёт от snyk</li>
15
<li>копируем snyk отчёт из артифактов в public (для pages)</li>
15
<li>копируем snyk отчёт из артифактов в public (для pages)</li>
16
</ul><h4>Информация в merge request в гитлаб</h4>
16
</ul><h4>Информация в merge request в гитлаб</h4>
17
<p>Если задать в проекте каталог .gitlab/merge_request_templates/, а в нём создать нужный вам description template в формате markdown, который затем можно выбирать при создании merge request. Я создал mr.md и в нём просто прописал ссылку на pages для проекта.</p>
17
<p>Если задать в проекте каталог .gitlab/merge_request_templates/, а в нём создать нужный вам description template в формате markdown, который затем можно выбирать при создании merge request. Я создал mr.md и в нём просто прописал ссылку на pages для проекта.</p>
18
<h2>Итог</h2>
18
<h2>Итог</h2>
19
<p>Перед мержем тим лид можно быстро перейти на отчёты по уязвимостям и сделать соответствующие выводы (на тему, хочет ли он это мержить либо нет).</p>
19
<p>Перед мержем тим лид можно быстро перейти на отчёты по уязвимостям и сделать соответствующие выводы (на тему, хочет ли он это мержить либо нет).</p>
20
20