HTML Diff
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 " &lt;html&gt; &lt;title&gt; CVE Reports for project ${CI_PROJECT_NAME}&lt;/title&gt; &lt;body&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=./snyk.html&gt;SNYK report&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=${CVE_URI}&gt;Harbor CVE report&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/body&gt; &lt;/html&gt; " &gt; 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 " &gt; 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 " &lt;html&gt; &lt;title&gt; CVE Reports for project ${CI_PROJECT_NAME}&lt;/title&gt; &lt;body&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=./snyk.html&gt;SNYK report&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=${CVE_URI}&gt;Harbor CVE report&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/body&gt; &lt;/html&gt; " &gt; 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 " &gt; 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