diff --git a/.github/workflows/mongodb_perf_build.yml b/.github/workflows/mongodb_perf_build.yml index 23fa641d01..a4fa072bd4 100644 --- a/.github/workflows/mongodb_perf_build.yml +++ b/.github/workflows/mongodb_perf_build.yml @@ -26,4 +26,4 @@ jobs: DOCKERHUB_PASSWORD: ${{ secrets.DOCKERHUB_PASSWORD }} run: docker login -u "${DOCKERHUB_USERNAME}" -p "${DOCKERHUB_PASSWORD}" - name: Build docker image - run: ./community_images/mongodb/bitnami/perf_test/build_docker.sh + run: ./community_images/mongodb/official/perf_test/build_docker.sh diff --git a/.github/workflows/prometheus_flaskapp_build.yml b/.github/workflows/prometheus_flaskapp_build.yml index 52790b78ad..722feefbba 100644 --- a/.github/workflows/prometheus_flaskapp_build.yml +++ b/.github/workflows/prometheus_flaskapp_build.yml @@ -26,4 +26,4 @@ jobs: DOCKERHUB_PASSWORD: ${{ secrets.DOCKERHUB_PASSWORD }} run: docker login -u "${DOCKERHUB_USERNAME}" -p "${DOCKERHUB_PASSWORD}" - name: Build docker image - run: ./community_images/prometheus/bitnami/build_docker.sh + run: ./community_images/prometheus/official/build_docker.sh diff --git a/README.md b/README.md index d3d77ac312..1d17aa3a22 100644 --- a/README.md +++ b/README.md @@ -362,7 +362,7 @@ $ helm repo add argo https://argoproj.github.io/argo-helm $ helm install my-argocd argo/argo-cd --set image.repository=rapidfort/argocd # install nats -$ helm install my-postgresql nats/nats --set image.repository=rapidfort/nats +$ helm install my-nats nats/nats --set image.repository=rapidfort/nats ``` ## How Community Images are Built @@ -414,7 +414,7 @@ Learn more about container optimization at [RapidFort.com][rf-link-additonal-res [dh-rf]: https://hub.docker.com/u/rapidfort [license-badge]: https://img.shields.io/github/license/rapidfort/community-images?color=lightgray&style=flat-square [license]: https://github.com/rapidfort/community-images/blob/main/LICENSE -[demo]: contrib/demo.gif +[demo]: contrib/rf-ci-demo.svg [slack-badge]: https://img.shields.io/static/v1?label=Join&message=slack&logo=slack&logoColor=E01E5A&color=4A154B [slack-link]: https://join.slack.com/t/rapidfortcommunity/shared_invite/zt-1g3wy28lv-DaeGexTQ5IjfpbmYW7Rm_Q diff --git a/TROUBLE_SHOOTING.md b/TROUBLE_SHOOTING.md index dc7566c632..bf4807f55d 100644 --- a/TROUBLE_SHOOTING.md +++ b/TROUBLE_SHOOTING.md @@ -22,7 +22,7 @@ The community images project relies on the upstream source images to work correc > Remediation: Please file a report and update the documentation for the image. 1. ### Upstream source image has introduced a defect (Source image error). - > Remediation: Please file a report on the source project. For eg: Bitnami Postgres image. + > Remediation: Please file a report on the source project. For eg: Docker Library Postgres image. 1. ### RapidFort hardened image is introducing a defect (RF error). > Remediation: Please report an issue, and we will work with our core engineering team to investigate and fix this issue. diff --git a/community_images/airflow/airflow/ironbank/README.md b/community_images/airflow/airflow/ironbank/README.md index a99efc6c91..75475bc02c 100644 --- a/community_images/airflow/airflow/ironbank/README.md +++ b/community_images/airflow/airflow/ironbank/README.md @@ -31,7 +31,7 @@ This optimized image is functionally equivalent to [Platform One Apache Airflow
-Every day, RapidFort automatically optimizes and hardens a growing bank of Docker Hub’s most important container images. +Every day, RapidFort automatically optimizes and hardens a growing bank of Docker Hub’s most important container images. Check out our [entire library of secured container images.](https://hub.docker.com/u/rapidfort)
@@ -65,69 +65,15 @@ The runtime instructions for this hardened container image are the same as the o
```sh -# Create a network -docker network create airflow-tier - -# Create a volume for PostgreSQL persistence and create a PostgreSQL container -docker volume create --name postgresql_data -docker run -d --name postgresql \ - -e POSTGRESQL_USERNAME=rf_airflow \ - -e POSTGRESQL_PASSWORD=rapidfort1 \ - -e POSTGRESQL_DATABASE=rapidfort_airflow \ - --net airflow-tier \ - --volume postgresql_data:/bitnami/postgresql \ - rapidfort/postgresql:latest - -# Create a volume for Redis(R) persistence and create a Redis(R) container -docker volume create --name redis_data -docker run -d --name redis \ - -e ALLOW_EMPTY_PASSWORD=yes \ - --net airflow-tier \ - --volume redis_data:/bitnami \ - rapidfort/redis:latest - -# Launch the Apache Airflow web container -docker run -d --name airflow -p 8080:8080 \ - -e AIRFLOW_FERNET_KEY=46BKJoQYlPPOexq0OhDZnIlNepKFf87WFwLbfzqDDho= \ - -e AIRFLOW_SECRET_KEY=a25mQ1FHTUh3MnFRSk5KMEIyVVU2YmN0VGRyYTVXY08= \ - -e AIRFLOW_EXECUTOR=CeleryExecutor \ - -e AIRFLOW_DATABASE_NAME=rapidfort_airflow \ - -e AIRFLOW_DATABASE_USERNAME=rf_airflow \ - -e AIRFLOW_DATABASE_PASSWORD=rapidfort1 \ - -e AIRFLOW_LOAD_EXAMPLES=yes \ - -e AIRFLOW_PASSWORD=rapidfort123 \ - -e AIRFLOW_USERNAME=user \ - -e AIRFLOW_EMAIL=user@example.com \ - --net airflow-tier \ - rapidfort/airflow-ib:latest - -# Launch the Apache Airflow scheduler container -docker run -d --name airflow-scheduler \ - -e AIRFLOW_COMPONENT_TYPE=scheduler \ - -e AIRFLOW_FERNET_KEY=46BKJoQYlPPOexq0OhDZnIlNepKFf87WFwLbfzqDDho= \ - -e AIRFLOW_SECRET_KEY=a25mQ1FHTUh3MnFRSk5KMEIyVVU2YmN0VGRyYTVXY08= \ - -e AIRFLOW_EXECUTOR=CeleryExecutor \ - -e AIRFLOW_DATABASE_NAME=rapidfort_airflow \ +# Run airflow worker scheduler and worker in same image +docker run -d --name airflow \ + -e AIRFLOW_DATABASE_NAME=rf_airflow \ -e AIRFLOW_DATABASE_USERNAME=rf_airflow \ - -e AIRFLOW_DATABASE_PASSWORD=rapidfort1 \ - -e AIRFLOW_LOAD_EXAMPLES=yes \ - -e AIRFLOW_WEBSERVER_HOST=airflow \ - --net airflow-tier \ - rapidfort/airflow-ib:latest - -# Launch the Apache Airflow worker container -docker run -d --name airflow-worker \ - -e AIRFLOW_COMPONENT_TYPE=worker \ - -e AIRFLOW_FERNET_KEY=46BKJoQYlPPOexq0OhDZnIlNepKFf87WFwLbfzqDDho= \ - -e AIRFLOW_SECRET_KEY=a25mQ1FHTUh3MnFRSk5KMEIyVVU2YmN0VGRyYTVXY08= \ + -e AIRFLOW_DATABASE_PASSWORD=s3cR31 \ -e AIRFLOW_EXECUTOR=CeleryExecutor \ - -e AIRFLOW_DATABASE_NAME=rapidfort_airflow \ - -e AIRFLOW_DATABASE_USERNAME=rf_airflow \ - -e AIRFLOW_DATABASE_PASSWORD=rapidfort1 \ - -e AIRFLOW_WEBSERVER_HOST=airflow \ - --net airflow-tier \ - rapidfort/airflow-ib:latest - + -e AIRFLOW__CORE__LOAD_EXAMPLES=true \ + rapidfort/airflow-ib:latest \ + bash -c "airflow db init && (airflow webserver & airflow scheduler)" ``` ## What is a hardened image? diff --git a/community_images/airflow/airflow/ironbank/image.yml b/community_images/airflow/airflow/ironbank/image.yml index 8444b2ff3c..1a3dbb33f5 100644 --- a/community_images/airflow/airflow/ironbank/image.yml +++ b/community_images/airflow/airflow/ironbank/image.yml @@ -10,68 +10,15 @@ image_workflow_name: airflow_airflow_ironbank github_location: airflow/airflow/ironbank report_url: https://us01.rapidfort.com/app/community/imageinfo/registry1.dso.mil%2Fironbank%2Fopensource%2Fapache%2Fairflow%2Fairflow usage_instructions: | - # Create a network - docker network create airflow-tier - - # Create a volume for PostgreSQL persistence and create a PostgreSQL container - docker volume create --name postgresql_data - docker run -d --name postgresql \ - -e POSTGRESQL_USERNAME=rf_airflow \ - -e POSTGRESQL_PASSWORD=rapidfort1 \ - -e POSTGRESQL_DATABASE=rapidfort_airflow \ - --net airflow-tier \ - --volume postgresql_data:/bitnami/postgresql \ - rapidfort/postgresql:latest - - # Create a volume for Redis(R) persistence and create a Redis(R) container - docker volume create --name redis_data - docker run -d --name redis \ - -e ALLOW_EMPTY_PASSWORD=yes \ - --net airflow-tier \ - --volume redis_data:/bitnami \ - rapidfort/redis:latest - - # Launch the Apache Airflow web container - docker run -d --name airflow -p 8080:8080 \ - -e AIRFLOW_FERNET_KEY=46BKJoQYlPPOexq0OhDZnIlNepKFf87WFwLbfzqDDho= \ - -e AIRFLOW_SECRET_KEY=a25mQ1FHTUh3MnFRSk5KMEIyVVU2YmN0VGRyYTVXY08= \ - -e AIRFLOW_EXECUTOR=CeleryExecutor \ - -e AIRFLOW_DATABASE_NAME=rapidfort_airflow \ + # Run airflow worker scheduler and worker in same image + docker run -d --name airflow \ + -e AIRFLOW_DATABASE_NAME=rf_airflow \ -e AIRFLOW_DATABASE_USERNAME=rf_airflow \ - -e AIRFLOW_DATABASE_PASSWORD=rapidfort1 \ - -e AIRFLOW_LOAD_EXAMPLES=yes \ - -e AIRFLOW_PASSWORD=rapidfort123 \ - -e AIRFLOW_USERNAME=user \ - -e AIRFLOW_EMAIL=user@example.com \ - --net airflow-tier \ - rapidfort/airflow-ib:latest - - # Launch the Apache Airflow scheduler container - docker run -d --name airflow-scheduler \ - -e AIRFLOW_COMPONENT_TYPE=scheduler \ - -e AIRFLOW_FERNET_KEY=46BKJoQYlPPOexq0OhDZnIlNepKFf87WFwLbfzqDDho= \ - -e AIRFLOW_SECRET_KEY=a25mQ1FHTUh3MnFRSk5KMEIyVVU2YmN0VGRyYTVXY08= \ + -e AIRFLOW_DATABASE_PASSWORD=s3cR31 \ -e AIRFLOW_EXECUTOR=CeleryExecutor \ - -e AIRFLOW_DATABASE_NAME=rapidfort_airflow \ - -e AIRFLOW_DATABASE_USERNAME=rf_airflow \ - -e AIRFLOW_DATABASE_PASSWORD=rapidfort1 \ - -e AIRFLOW_LOAD_EXAMPLES=yes \ - -e AIRFLOW_WEBSERVER_HOST=airflow \ - --net airflow-tier \ - rapidfort/airflow-ib:latest - - # Launch the Apache Airflow worker container - docker run -d --name airflow-worker \ - -e AIRFLOW_COMPONENT_TYPE=worker \ - -e AIRFLOW_FERNET_KEY=46BKJoQYlPPOexq0OhDZnIlNepKFf87WFwLbfzqDDho= \ - -e AIRFLOW_SECRET_KEY=a25mQ1FHTUh3MnFRSk5KMEIyVVU2YmN0VGRyYTVXY08= \ - -e AIRFLOW_EXECUTOR=CeleryExecutor \ - -e AIRFLOW_DATABASE_NAME=rapidfort_airflow \ - -e AIRFLOW_DATABASE_USERNAME=rf_airflow \ - -e AIRFLOW_DATABASE_PASSWORD=rapidfort1 \ - -e AIRFLOW_WEBSERVER_HOST=airflow \ - --net airflow-tier \ - rapidfort/airflow-ib:latest + -e AIRFLOW__CORE__LOAD_EXAMPLES=true \ + rapidfort/airflow-ib:latest \ + bash -c "airflow db init && (airflow webserver & airflow scheduler)" what_is_text: | Apache Airflow (or simply Airflow) is a platform to programmatically author, schedule, and monitor workflows. diff --git a/community_images/common/templates/main_readme.j2 b/community_images/common/templates/main_readme.j2 index 58bd69d766..86c45d8576 100644 --- a/community_images/common/templates/main_readme.j2 +++ b/community_images/common/templates/main_readme.j2 @@ -79,7 +79,7 @@ $ helm repo add argo https://argoproj.github.io/argo-helm $ helm install my-argocd argo/argo-cd --set image.repository=rapidfort/argocd # install nats -$ helm install my-postgresql nats/nats --set image.repository=rapidfort/nats +$ helm install my-nats nats/nats --set image.repository=rapidfort/nats ``` ## How Community Images are Built @@ -131,7 +131,7 @@ Learn more about container optimization at [RapidFort.com][rf-link-additonal-res [dh-rf]: https://hub.docker.com/u/rapidfort [license-badge]: https://img.shields.io/github/license/rapidfort/community-images?color=lightgray&style=flat-square [license]: https://github.com/rapidfort/community-images/blob/main/LICENSE -[demo]: contrib/demo.gif +[demo]: contrib/rf-ci-demo.svg [slack-badge]: https://img.shields.io/static/v1?label=Join&message=slack&logo=slack&logoColor=E01E5A&color=4A154B [slack-link]: https://join.slack.com/t/rapidfortcommunity/shared_invite/zt-1g3wy28lv-DaeGexTQ5IjfpbmYW7Rm_Q diff --git a/community_images/template/provider/image.yml b/community_images/template/provider/image.yml index 4f6ad4c3a6..159b988a73 100644 --- a/community_images/template/provider/image.yml +++ b/community_images/template/provider/image.yml @@ -1,19 +1,19 @@ name: community-image official_name: RapidFort Community Images official_website: https://rapidfort.com -source_image_provider: Bitnami +source_image_provider: Provider source_image_repo: docker.io/provider/template source_image_repo_link: https://hub.docker.com/r/provider/template -source_image_readme: https://github.com/bitnami/containers/blob/main/bitnami/consul/README.md +source_image_readme: https://github.com/provider/containers/blob/main/image/README.md rf_docker_link: rapidfort/template image_workflow_name: template_provider github_location: template/provider -report_url: https://us01.rapidfort.com/app/community/imageinfo/docker.io%2Fbitnami%2Fredis +report_url: https://us01.rapidfort.com/app/community/imageinfo/docker.io%2Fprovider%2Ftemplate usage_instructions: | - $ helm repo add bitnami https://charts.bitnami.com/bitnami + $ helm repo add provider https://charts.provider.com/provider - # install mariadb, just replace repository with RapidFort registry - $ helm install my-nginx bitnami/template --set image.repository=rapidfort/template + # install image, just replace repository with RapidFort registry + $ helm install my-image provider/template --set image.repository=rapidfort/template what_is_text: | Please replace this with the details about the source image you are hardening. disclaimer: | @@ -21,7 +21,7 @@ disclaimer: | is_locked: "False" input_registry: registry: docker.io - account: bitnami + account: provider repo_sets: - redis: input_base_tag: "7.0.3-debian-11-r" @@ -31,8 +31,8 @@ runtimes: - type: k8s script: k8s_coverage.sh helm: - repo: bitnami - repo_url: https://charts.bitnami.com/bitnami + repo: provider + repo_url: https://charts.provider.com/provider chart: nats tls_certs: generate: true @@ -60,5 +60,5 @@ runtimes: environment: KEY_FOO: VAL_BAR volumes: - configs/dynamic/bootstrap.yaml: /opt/bitnami/redis/conf/redis.yaml + configs/dynamic/bootstrap.yaml: /opt/provider/image/conf/redis.yaml configs/dynamic: /etc/redis diff --git a/contrib/rf-ci-demo.svg b/contrib/rf-ci-demo.svg new file mode 100644 index 0000000000..a34a8344fb --- /dev/null +++ b/contrib/rf-ci-demo.svg @@ -0,0 +1,267 @@ + + + + + + + + + + + + + + ~ $ ~ $ d ~ $ do ~ $ doc ~ $ dock ~ $ docke ~ $ docker ~ $ docker ~ $ docker r ~ $ docker ru ~ $ docker run ~ $ docker run ~ $ docker run - ~ $ docker run -- ~ $ docker run --n ~ $ docker run --na ~ $ docker run --nam ~ $ docker run --name ~ $ docker run --name ~ $ docker run --name m ~ $ docker run --name my ~ $ docker run --name my- ~ $ docker run --name my-n ~ $ docker run --name my-ng ~ $ docker run --name my-ngi ~ $ docker run --name my-ngin ~ $ docker run --name my-nginx ~ $ docker run --name my-nginx- ~ $ docker run --name my-nginx-a ~ $ docker run --name my-nginx-ap ~ $ docker run --name my-nginx-app ~ $ docker run --name my-nginx-app ~ $ docker run --name my-nginx-app - ~ $ docker run --name my-nginx-app -p ~ $ docker run --name my-nginx-app -p ~ $ docker run --name my-nginx-app -p 8 ~ $ docker run --name my-nginx-app -p 80 ~ $ docker run --name my-nginx-app -p 808 ~ $ docker run --name my-nginx-app -p 8080 ~ $ docker run --name my-nginx-app -p 8080: ~ $ docker run --name my-nginx-app -p 8080:8 ~ $ docker run --name my-nginx-app -p 8080:80 ~ $ docker run --name my-nginx-app -p 8080:80 ~ $ docker run --name my-nginx-app -p 8080:80 - ~ $ docker run --name my-nginx-app -p 8080:80 -v ~ $ docker run --name my-nginx-app -p 8080:80 -v ~ $ docker run --name my-nginx-app -p 8080:80 -v $ ~ $ docker run --name my-nginx-app -p 8080:80 -v ${ ~ $ docker run --name my-nginx-app -p 8080:80 -v ${P ~ $ docker run --name my-nginx-app -p 8080:80 -v ${PW ~ $ docker run --name my-nginx-app -p 8080:80 -v ${PWD ~ $ docker run --name my-nginx-app -p 8080:80 -v ${PWD} ~ $ docker run --name my-nginx-app -p 8080:80 -v ${PWD}/ ~ $ docker run --name my-nginx-app -p 8080:80 -v ${PWD}/a ~ $ docker run --name my-nginx-app -p 8080:80 -v ${PWD}/ap ~ $ docker run --name my-nginx-app -p 8080:80 -v ${PWD}/app ~ $ docker run --name my-nginx-app -p 8080:80 -v ${PWD}/app: ~ $ docker run --name my-nginx-app -p 8080:80 -v ${PWD}/app:/ ~ $ docker run --name my-nginx-app -p 8080:80 -v ${PWD}/app:/u ~ $ docker run --name my-nginx-app -p 8080:80 -v ${PWD}/app:/us ~ $ docker run --name my-nginx-app -p 8080:80 -v ${PWD}/app:/usr ~ $ docker run --name my-nginx-app -p 8080:80 -v ${PWD}/app:/usr/ ~ $ docker run --name my-nginx-app -p 8080:80 -v ${PWD}/app:/usr/s ~ $ docker run --name my-nginx-app -p 8080:80 -v ${PWD}/app:/usr/sh ~ $ docker run --name my-nginx-app -p 8080:80 -v ${PWD}/app:/usr/sha ~ $ docker run --name my-nginx-app -p 8080:80 -v ${PWD}/app:/usr/shar ~ $ docker run --name my-nginx-app -p 8080:80 -v ${PWD}/app:/usr/share ~ $ docker run --name my-nginx-app -p 8080:80 -v ${PWD}/app:/usr/share/ ~ $ docker run --name my-nginx-app -p 8080:80 -v ${PWD}/app:/usr/share/n g gi gin ginx ginx/ ginx/h ginx/ht ginx/htm ginx/html ginx/html: ginx/html:r ginx/html:ro ginx/html:ro ginx/html:ro - ginx/html:ro -d ginx/html:ro -d ginx/html:ro -d r ginx/html:ro -d ra ginx/html:ro -d rap ginx/html:ro -d rapi ginx/html:ro -d rapid ginx/html:ro -d rapidf ginx/html:ro -d rapidfo ginx/html:ro -d rapidfor ginx/html:ro -d rapidfort/ ginx/html:ro -d rapidfort/n ginx/html:ro -d rapidfort/ng ginx/html:ro -d rapidfort/ngi ginx/html:ro -d rapidfort/ngin ginx/html:ro -d rapidfort/nginx ginx/html:ro -d rapidfort/nginx- ginx/html:ro -d rapidfort/nginx-o ginx/html:ro -d rapidfort/nginx-of ginx/html:ro -d rapidfort/nginx-off ginx/html:ro -d rapidfort/nginx-offi ginx/html:ro -d rapidfort/nginx-offic ginx/html:ro -d rapidfort/nginx-offici ginx/html:ro -d rapidfort/nginx-officia ginx/html:ro -d rapidfort/nginx-official ginx/html:ro -d rapidfort/nginx-official: ginx/html:ro -d rapidfort/nginx-official:l ginx/html:ro -d rapidfort/nginx-official:la ginx/html:ro -d rapidfort/nginx-official:lat ginx/html:ro -d rapidfort/nginx-official:late ginx/html:ro -d rapidfort/nginx-official:lates ginx/html:ro -d rapidfort/nginx-official:latest ginx/html:ro -d rapidfort/nginx-official:latestUnable to find image 'rapidfort/nginx-official:latest' locallylatest: Pulling from rapidfort/nginx-official0910cc9a0bbb: Pulling fs layer 0910cc9a0bbb: Downloading 261.4kB/25.43MB 0910cc9a0bbb: Downloading 11.27MB/25.43MB 0910cc9a0bbb: Downloading 22.54MB/25.43MB 0910cc9a0bbb: Download complete 0910cc9a0bbb: Extracting 262.1kB/25.43MB 0910cc9a0bbb: Extracting 1.311MB/25.43MB 0910cc9a0bbb: Extracting 4.456MB/25.43MB 0910cc9a0bbb: Extracting 8.126MB/25.43MB 0910cc9a0bbb: Extracting 12.85MB/25.43MB 0910cc9a0bbb: Extracting 18.35MB/25.43MB 0910cc9a0bbb: Extracting 23.33MB/25.43MB 0910cc9a0bbb: Extracting 24.9MB/25.43MB 0910cc9a0bbb: Extracting 25.43MB/25.43MB 0910cc9a0bbb: Pull complete Digest: sha256:ec0405b97a8489155df1557a1043644c745e9b12e09fd32b6dca8513950285e1Status: Downloaded newer image for rapidfort/nginx-official:latest5e6f2c8856c7f08152fa653b3437f0a1e7de643833f1dd0571689049f815cf72~ $ ~ $ d ~ $ do ~ $ doc ~ $ dock ~ $ docke ~ $ docker ~ $ docker ~ $ docker l ~ $ docker lo ~ $ docker log ~ $ docker logs ~ $ docker logs ~ $ docker logs m ~ $ docker logs my ~ $ docker logs my- ~ $ docker logs my-n ~ $ docker logs my-ng ~ $ docker logs my-ngi ~ $ docker logs my-ngin ~ $ docker logs my-nginx ~ $ docker logs my-nginx- ~ $ docker logs my-nginx-a ~ $ docker logs my-nginx-ap ~ $ docker logs my-nginx-app ~ $ docker logs my-nginx-app 10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh/docker-entrypoint.sh: Configuration complete; ready for start up2025/01/16 07:43:50 [notice] 1#1: using the "epoll" event method2025/01/16 07:43:50 [notice] 1#1: nginx/1.24.02025/01/16 07:43:50 [notice] 1#1: built by gcc 10.2.1 20210110 (Debian 10.2.1-6) 2025/01/16 07:43:50 [notice] 1#1: OS: Linux 6.8.2-trux122025/01/16 07:43:50 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:10485762025/01 2025/01/16 07:43:50 [notice] 1#1: start worker process 292025/01/16 07:43:50 [notice] 1#1: start worker process 302025/01/16 07:43:50 [notice] 1#1: start worker process 312025/01/16 07:43:50 [notice] 1#1: start worker process 322025/01/16 07:43:50 [notice] 1#1: start worker process 332025/01/16 07:43:50 [notice] 1#1: start worker process 342025/01/16 07:43:50 [notice] 1#1: start worker process 352025/01/16 07:43:50 [notice] 1#1: start worker process 362025/01/16 07:43:50 [notice] 1#1: start worker process 372025/01/16 07:43:50 [notice] 1#1: start worker process 382025/01/16 07:43:50 [notice] 1#1: start worker process 392025/01/16 07:43:50 [notice] 1#1: start worker process 402025/01/16 07:43:50 [notice] 1#1: start worker process 412025/01/16 07:43:50 [notice] 1#1: start worker process 422025/01/16 07:43:50 [notice] 1#1: start worker process 432025/01/16 07:43:50 [notice] 1#1: start worker process 44~ $ c ~ $ cu ~ $ cur ~ $ curl ~ $ curl ~ $ curl l ~ $ curl lo ~ $ curl loc ~ $ curl loca ~ $ curl local ~ $ curl localh ~ $ curl localho ~ $ curl localhos ~ $ curl localhost ~ $ curl localhost: ~ $ curl localhost:8 ~ $ curl localhost:80 ~ $ curl localhost:808 ~ $ curl localhost:8080 ~ $ curl localhost:8080 Hi from RapidFort Nginx.~ $ exit + + \ No newline at end of file diff --git a/report_shots/shots.js b/report_shots/shots.js index 6b25ad5581..7c1d6b9bed 100644 --- a/report_shots/shots.js +++ b/report_shots/shots.js @@ -17,22 +17,22 @@ function saveSVGToFile(svgContent, imageSavePath) { }); } -// generate rect path with rounded top left and right corners +// generate rect path with rounded top left and right corners function createRoundedRectPath(x, y, width, height, radius) { if (height < radius) { radius = height; } return ` - M${x + radius},${y} - H${x + width - radius} - C${x + width},${y} ${x + width},${y} ${x + width},${y + radius} - V${y + height} - H${x} - V${y + radius} + M${x + radius},${y} + H${x + width - radius} + C${x + width},${y} ${x + width},${y} ${x + width},${y + radius} + V${y + height} + H${x} + V${y + radius} C${x},${y} ${x},${y} ${x + radius},${y} Z `; -} +} const generateCharts = async (imageName, platform, imageSavePath) => { const fetchDataRequest = async (path)=> { @@ -65,7 +65,7 @@ const generateCharts = async (imageName, platform, imageSavePath) => { const vulnsHardened = await fetchDataRequest(jsonInfo?.vulns_hardened); const {vulnsSeverityCount: vulnsHardenedSummary, hardenedVulnsFlags, } = convertVulnsData(vulnsHardened, true, true); const {vulnsSeverityCount: vulnsOriginalSummary} = convertVulnsData(vulns, true, false, hardenedVulnsFlags); - + // generate SVGs // const vulnsSavingsChartSVG = await generateSavingsChart('Vulnerabilities', imageInfo.noVulns, imageInfo.noVulnsHardened, false); // const packagesSavingsChartSVG = await generateSavingsChart('Packages', imageInfo.noPkgs, imageInfo.noPkgsHardened, false); @@ -74,20 +74,20 @@ const generateCharts = async (imageName, platform, imageSavePath) => { // const vulnsBySeverityChart = await generateVulnsBySeverityChart(vulnsOriginalSummary.default, vulnsHardenedSummary.default); const {width, svg:vulnsCountChartSVG} = await generateVulnsCountChart(vulnsHardenedSummary.default); const vulnsOriginalHardenedChartSVG = await generateVulnsOriginalHardenedChart(width, vulnsOriginalSummary.default, vulnsHardenedSummary.default); - + saveSVGToFile(vulnsCountChartSVG, util.format('%s/vulns_count_chart.svg', imageSavePath)); saveSVGToFile(vulnsOriginalHardenedChartSVG, util.format('%s/original_vs_hardened_vulns_chart.svg', imageSavePath)); const vulnsChartMergedSvg = await mergeSvgHorizontally([vulnsCountChartSVG, vulnsOriginalHardenedChartSVG], 24); - + saveSVGToFile(vulnsChartMergedSvg, util.format('%s/vulns_charts.svg', imageSavePath)); const savingsSVG = await generateSavingsCardsCompound([ { type:'vulns', - title:'Vulnerabilities', - original: imageInfo.noVulns, - hardened:imageInfo.noVulnsHardened, + title:'Vulnerabilities', + original: imageInfo.noVulns, + hardened:imageInfo.noVulnsHardened, isSize:false, }, { @@ -113,7 +113,7 @@ const generateCharts = async (imageName, platform, imageSavePath) => { // saveSVGToFile(contextualSeverityChart, util.format('%s/contextual_severity_chart.svg', imageSavePath)); // saveSVGToFile(vulnsBySeverityChart, util.format('%s/vulns_by_severity_histogram.svg', imageSavePath)); // generateReportViews(vulnsSavingsChartSVG, packagesSavingsChartSVG, sizeSavingsChartSVG, contextualSeverityChart, vulnsBySeverityChart, imageSavePath); - + } catch (error) { console.error(error); } @@ -127,7 +127,7 @@ const findSVGDimensions = (node) => { height: parseFloat(node.attributes.height), }; } - + for (const child of node.children || []) { const dimensions = findSVGDimensions(child); if (dimensions) return dimensions; @@ -169,7 +169,7 @@ const generateReportViews = async ( const styleMatch = svgContent.match(/]*>([\s\S]*?)<\/style>/); if (styleMatch) { const styleContent = styleMatch[1]; - + // Match and deduplicate @font-face const fontFaceMatches = styleContent.match(/@font-face\s*{[^}]*}/g) || []; fontFaceMatches.forEach(fontFace => uniqueFontFaces.add(fontFace)); @@ -194,7 +194,7 @@ const generateReportViews = async ( const cleanedSVGs = svgFiles.map(svgContent => svgContent.replace(/]*>[\s\S]*?<\/style>/, "") ); - + const dimensions = await Promise.all(svgFiles.map(parseSVGDimensions)); const severityVulnsDimensions = dimensions[0] @@ -302,12 +302,12 @@ const updateText = (draw, selector, newText) => { // Generating chart savings chart (vulns, packages, size) /** - * + * * @param {String} title chart title * @param {Number} original original value * @param {Number} hardened hardened value * @param {Boolean} isSize if size then need to show values with metrics suffix - * @returns + * @returns */ async function generateSavingsChart(title, original, hardened, isSize) { // preparing data @@ -363,12 +363,12 @@ async function generateSavingsChart(title, original, hardened, isSize) { } /** - * + * * @param {*} original original data usual severity object {critical:n, high:m, ...} * @param {*} hardened hardened data usual severity object {critical:n, high:m, ...} * @returns {String} svg string */ -async function generateVulnsBySeverityChart(original, hardened) { +async function generateVulnsBySeverityChart(original, hardened) { // preparing data for chart const severities = ['poc', 'critical', 'high', 'medium', 'low', 'unknown', 'na']; const datasets = ['original', 'hardened']; @@ -390,27 +390,27 @@ async function generateVulnsBySeverityChart(original, hardened) { severities.forEach((severity) => { const mask = draw.defs().mask().id(`mask_${severity}`); - + datasets.forEach((dataset) => { const summary = dataset === 'original' ? original : hardened; const value = summary[severity]; const columnId = `column_${dataset}_${severity}`; const pathElement = draw.findOne(`#${columnId}`); - + if (pathElement) { const width = 28; // Bar width const radius = 5; // border radius for bar const height = calculateHeight(value); const baseY = 85; // bottom line y for bars (all bars aligned at bottom) - + // get new y value and generate new value for path element const x = parseFloat(pathElement.attr('d').match(/M(\d+\.?\d*)/)[1]); const newPath = createRoundedRectPath(x - 26, baseY - height, width, height, radius); - + // updating d and fill attributes pathElement.attr('d', newPath); pathElement.attr('fill', `${vulnsColorScheme[severity]}${dataset === 'original' ? '33' : 'ff'}`); - + // creating mask only for original (original view will be always bg for hardened) if (dataset === 'original') { // adding rectangular mask with border radius for certain coords and size @@ -421,7 +421,7 @@ async function generateVulnsBySeverityChart(original, hardened) { } // applying mask to current element pathElement.attr('mask', `url(#mask_${severity})`); - + // updating text value const textSpanElement = updateText(draw, `#${dataset}_${severity}`, value.toString()); if (textSpanElement && dataset === 'original') { @@ -432,7 +432,7 @@ async function generateVulnsBySeverityChart(original, hardened) { }); }); - // return svg string + // return svg string return draw.svg(); } @@ -454,7 +454,7 @@ async function generateContextualSeverityChart(vulnsOriginalSummary) { // compute step for chart y ticks function calculateStep(maxValue) { const magnitude = Math.pow(10, Math.floor(Math.log10(maxValue))); - const factors = [1, 2, 5]; + const factors = [1, 2, 5]; for (let factor of factors) { const step = magnitude * factor; if (maxValue / step <= 2) { @@ -462,7 +462,7 @@ async function generateContextualSeverityChart(vulnsOriginalSummary) { } } - return magnitude * 10; + return magnitude * 10; } const step = calculateStep(maxVal); @@ -472,9 +472,9 @@ async function generateContextualSeverityChart(vulnsOriginalSummary) { const maxHeight = 50; // max bar height return (value / maxVal) * maxHeight; }; - + const draw = await prepareSVG('template_contextual_severity'); - + // updating height and position for every bar severities.forEach((severity) => { datasets.forEach((dataset) => { @@ -524,7 +524,7 @@ async function generateContextualSeverityChart(vulnsOriginalSummary) { } /** * Draws a chart in an SVG based on the provided data. - * + * * @param {Object} draw - SVG.js object. * @param {string} groupId - ID of the group where the chart will be added. * @param {number} maxWidth - Maximum width of the chart. @@ -533,7 +533,7 @@ async function generateContextualSeverityChart(vulnsOriginalSummary) { */ function drawVulnsChart(draw, groupId, maxWidth, vulnsCount, total) { const severities = ['critical', 'high', 'medium', 'low', 'unknown'].filter(l => vulnsCount[l] > 0); - + const minWidth = 5; const spacing = 2; @@ -580,9 +580,9 @@ function drawVulnsChart(draw, groupId, maxWidth, vulnsCount, total) { /** - * - * @param {*} vulnsCount - * @returns + * + * @param {*} vulnsCount + * @returns */ async function generateVulnsCountChart(vulnsCount) { // Preparing data for chart @@ -615,8 +615,8 @@ async function generateVulnsCountChart(vulnsCount) { // Update the total count text updateText(draw, '#vulns_total', vulnsCount.total); - draw.width(contentWidth + 48); - const currentViewBox = draw.attr('viewBox') || '0 0 100 100'; + draw.width(contentWidth + 48); + const currentViewBox = draw.attr('viewBox') || '0 0 100 100'; const [x, y, , originalHeight] = currentViewBox.split(' ').map(Number); const newWidth = contentWidth + 48; const updatedViewBox = `${x} ${y} ${newWidth} ${originalHeight}`; @@ -628,9 +628,9 @@ async function generateVulnsCountChart(vulnsCount) { /** - * - * @param {*} vulnsCount - * @returns + * + * @param {*} vulnsCount + * @returns */ async function generateVulnsOriginalHardenedChart(cardWidth, original, hardened) { // Preparing data for chart @@ -648,10 +648,10 @@ async function generateVulnsOriginalHardenedChart(cardWidth, original, hardened) draw.findOne(`#original_value_tspan`).attr('x', cardWidth - originalValueTextWidth - 24) draw.findOne(`#original_mask`).attr('width', cardWidth - originalValueTextWidth - 24 - 10 - 106) draw.findOne(`#original_mask_rect`).attr('width', cardWidth - originalValueTextWidth - 24 - 10 - 106) - + Object.entries(data).forEach(([key, vulnsCount]) => { if (original.total === 0) { - return + return } let contentWidth = cardWidth - originalValueTextWidth - 24 - 10 - 106; if (key === 'hardened') { @@ -667,8 +667,8 @@ async function generateVulnsOriginalHardenedChart(cardWidth, original, hardened) updateText(draw, `#${key}_value`, vulnsCount.total); }) - draw.width(cardWidth); - const currentViewBox = draw.attr('viewBox'); + draw.width(cardWidth); + const currentViewBox = draw.attr('viewBox'); const [x, y, , originalHeight] = currentViewBox.split(' ').map(Number); const updatedViewBox = `${x} ${y} ${cardWidth} ${originalHeight}`; draw.attr('viewBox', updatedViewBox); @@ -678,12 +678,12 @@ async function generateVulnsOriginalHardenedChart(cardWidth, original, hardened) // Generating chart savings chart (vulns, packages, size) /** - * + * * @param {String} title chart title * @param {Number} original original value * @param {Number} hardened hardened value * @param {Boolean} isSize if size then need to show values with metrics suffix - * @returns + * @returns */ async function generateSavingsCardsCompound(savingsData) { const draw = await prepareSVG('template_savings_view') @@ -708,7 +708,7 @@ async function generateSavingsCardsCompound(savingsData) { const dashOffset = calculateDashoffset(100 - percentage, dashArray); // set value for circle as progress bar const progressCircle = draw.findOne(`#${type}_progress`); - + progressCircle.attr({ 'stroke-dasharray': dashArray, 'stroke-dashoffset': dashOffset, @@ -791,10 +791,10 @@ async function main() { const imgList = await fsPromise.readFile(imgListPath, { encoding: 'utf8' }); const imgListArray = imgList.split("\n"); - // const imgListArray = ['apache/bitnami']; + // const imgListArray = ['apache/official']; for await (const imagePath of imgListArray) { - + try { let imageYmlPath = fs.realpathSync(util.format('../community_images/%s/image.yml', imagePath)); diff --git a/scripts/prepare_image_yml.py b/scripts/prepare_image_yml.py index 4a727631ce..807687b4d8 100644 --- a/scripts/prepare_image_yml.py +++ b/scripts/prepare_image_yml.py @@ -1,6 +1,5 @@ """ Merges tags into image.yml """ import sys -import os import logging import yaml