From b58cc9fe03eff097dc7a80fcd8c5e7eec8046cfc Mon Sep 17 00:00:00 2001 From: meleksabit Date: Thu, 29 Aug 2024 02:19:45 +0300 Subject: [PATCH 01/19] add devsecops_pipeline.py --- devsecops_pipeline.py | 64 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 devsecops_pipeline.py diff --git a/devsecops_pipeline.py b/devsecops_pipeline.py new file mode 100644 index 0000000..045a782 --- /dev/null +++ b/devsecops_pipeline.py @@ -0,0 +1,64 @@ +import os +import subprocess +import sys + +# Helper function to run shell commands +def run_command(command, cwd=None): + result = subprocess.run(command, shell=True, cwd=cwd, text=True, capture_output=True) + if result.returncode != 0: + print(f"Error: Command '{command}' failed with exit code {result.returncode}") + print(result.stdout) + print(result.stderr) + sys.exit(result.returncode) + return result.stdout + +# Static Code Analysis and Code Coverage (using SonarQube) +def run_sonarqube_analysis(path): + print("Running SonarQube for static code analysis and code coverage...") + run_command(f"sonar-scanner -Dsonar.projectBaseDir={path}") + +# Dependency Checking (using Safety) +def run_safety(): + print("Running Safety for dependency checking...") + run_command("safety check --full-report") + +# Secret Scanning (using TruffleHog) +def run_trufflehog(path): + print("Running TruffleHog for secret scanning...") + run_command(f"trufflehog {path}") + +# Infrastructure as Code Scanning (using Terraform and Snyk) +def run_terraform_scan(path): + print("Running Snyk for Terraform IaC scanning...") + run_command(f"snyk iac test {path}") + +# Code Coverage and Linting (using Pylint) +def run_pylint(path): + print("Running Pylint for code linting...") + run_command(f"pylint {path}") + +# Main function to orchestrate the DevSecOps pipeline +def main(): + project_path = os.getcwd() + + # Static Analysis and Code Coverage with SonarQube + run_sonarqube_analysis(project_path) + + # Dependency Checking + run_safety() + + # Secret Scanning + run_trufflehog(project_path) + + # Terraform IaC Scanning + terraform_path = os.path.join(project_path, 'terraform') + if os.path.exists(terraform_path): + run_terraform_scan(terraform_path) + + # Linting + run_pylint(project_path) + + print("DevSecOps pipeline completed successfully!") + +if __name__ == "__main__": + main() From 8c039b1b89b344a308ad062fe1ecce6ee2ccaf2d Mon Sep 17 00:00:00 2001 From: meleksabit Date: Thu, 29 Aug 2024 03:42:33 +0300 Subject: [PATCH 02/19] add devsecops-pipeline workflow --- .github/workflows/devsecops-pipeline.yml | 30 ++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 .github/workflows/devsecops-pipeline.yml diff --git a/.github/workflows/devsecops-pipeline.yml b/.github/workflows/devsecops-pipeline.yml new file mode 100644 index 0000000..c8dd3ac --- /dev/null +++ b/.github/workflows/devsecops-pipeline.yml @@ -0,0 +1,30 @@ +name: DevSecOps Pipeline + +on: + push: + branches: + - main + pull_request: + branches: + - main + +jobs: + security-checks: + runs-on: ubuntu-latest + + steps: + - name: Checkout Code + uses: actions/checkout@v2 + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install Dependencies + run: | + python -m pip install --upgrade pip + pip install safety truffleHog sonar-scanner + + - name: Run DevSecOps Pipeline + run: python devsecops_pipeline.py From d3e5daffd2a45a75875b9364638c80375c425ffb Mon Sep 17 00:00:00 2001 From: meleksabit Date: Thu, 29 Aug 2024 03:51:51 +0300 Subject: [PATCH 03/19] replace sonarqube with bandit --- .github/workflows/devsecops-pipeline.yml | 2 +- devsecops_pipeline.py | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/devsecops-pipeline.yml b/.github/workflows/devsecops-pipeline.yml index c8dd3ac..6d1d69a 100644 --- a/.github/workflows/devsecops-pipeline.yml +++ b/.github/workflows/devsecops-pipeline.yml @@ -24,7 +24,7 @@ jobs: - name: Install Dependencies run: | python -m pip install --upgrade pip - pip install safety truffleHog sonar-scanner + pip install bandit safety truffleHog pylint - name: Run DevSecOps Pipeline run: python devsecops_pipeline.py diff --git a/devsecops_pipeline.py b/devsecops_pipeline.py index 045a782..d12a21c 100644 --- a/devsecops_pipeline.py +++ b/devsecops_pipeline.py @@ -12,10 +12,10 @@ def run_command(command, cwd=None): sys.exit(result.returncode) return result.stdout -# Static Code Analysis and Code Coverage (using SonarQube) -def run_sonarqube_analysis(path): - print("Running SonarQube for static code analysis and code coverage...") - run_command(f"sonar-scanner -Dsonar.projectBaseDir={path}") +# Static Code Analysis (using Bandit) +def run_bandit(path): + print("Running Bandit for static code analysis...") + run_command(f"bandit -r {path}") # Dependency Checking (using Safety) def run_safety(): @@ -41,8 +41,8 @@ def run_pylint(path): def main(): project_path = os.getcwd() - # Static Analysis and Code Coverage with SonarQube - run_sonarqube_analysis(project_path) + # Static Analysis + run_bandit(project_path) # Dependency Checking run_safety() @@ -54,7 +54,7 @@ def main(): terraform_path = os.path.join(project_path, 'terraform') if os.path.exists(terraform_path): run_terraform_scan(terraform_path) - + # Linting run_pylint(project_path) From bfc3f90ac7bf7fa5211525536ddf52fc8390f1c9 Mon Sep 17 00:00:00 2001 From: meleksabit Date: Fri, 6 Sep 2024 02:30:59 +0300 Subject: [PATCH 04/19] edit cron job --- .github/workflows/codeql.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 4688f97..e8c440e 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -17,7 +17,7 @@ on: pull_request: branches: [ "main" ] schedule: - - cron: '39 23 * * 1' + - cron: '33 23 * * 1' jobs: analyze: From 80ec32ca2267b8fcc0e178a8e4c2968a51043a20 Mon Sep 17 00:00:00 2001 From: meleksabit Date: Sun, 8 Sep 2024 03:08:46 +0300 Subject: [PATCH 05/19] add comment for the cron job --- .github/workflows/codeql.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index e8c440e..cddd97a 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -17,7 +17,7 @@ on: pull_request: branches: [ "main" ] schedule: - - cron: '33 23 * * 1' + - cron: '33 23 * * 1' # CodeQL will run every Monday at 23:33 UTC jobs: analyze: From b57b3ca35c57658ec6c051091ed02e009bf2f552 Mon Sep 17 00:00:00 2001 From: meleksabit Date: Wed, 11 Sep 2024 16:51:31 +0300 Subject: [PATCH 06/19] add Git Guardian workflow --- .github/workflows/gitguardian.yml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 .github/workflows/gitguardian.yml diff --git a/.github/workflows/gitguardian.yml b/.github/workflows/gitguardian.yml new file mode 100644 index 0000000..13696eb --- /dev/null +++ b/.github/workflows/gitguardian.yml @@ -0,0 +1,23 @@ +name: GitGuardian Scan + +on: + push: + branches: + - main + pull_request: + branches: + - main + +jobs: + ggshield: + name: GitGuardian Secret Detection + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Run GitGuardian ggshield + uses: GitGuardian/ggshield-action@v1 + with: + api-key: ${{ secrets.GITGUARDIAN_API_KEY }} From 0e76968b353db66d604c8857f515661d44905a1b Mon Sep 17 00:00:00 2001 From: meleksabit Date: Wed, 11 Sep 2024 17:01:09 +0300 Subject: [PATCH 07/19] edit Git Guardian workflow --- .github/workflows/gitguardian.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/gitguardian.yml b/.github/workflows/gitguardian.yml index 13696eb..be38e87 100644 --- a/.github/workflows/gitguardian.yml +++ b/.github/workflows/gitguardian.yml @@ -2,7 +2,7 @@ name: GitGuardian Scan on: push: - branches: + branches: - main pull_request: branches: @@ -10,14 +10,15 @@ on: jobs: ggshield: - name: GitGuardian Secret Detection + name: GitGuardian Scan runs-on: ubuntu-latest - steps: - name: Checkout code uses: actions/checkout@v3 - - name: Run GitGuardian ggshield + - name: Run GitGuardian ggshield scan uses: GitGuardian/ggshield-action@v1 with: - api-key: ${{ secrets.GITGUARDIAN_API_KEY }} + args: scan path --exit-zero . + env: + GITGUARDIAN_API_KEY: ${{ secrets.GITGUARDIAN_API_KEY }} From b96d528921912a79b52cab6340786a55e235c2ea Mon Sep 17 00:00:00 2001 From: meleksabit Date: Wed, 11 Sep 2024 17:08:07 +0300 Subject: [PATCH 08/19] edit Git Guardian workflow --- .github/workflows/gitguardian.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/gitguardian.yml b/.github/workflows/gitguardian.yml index be38e87..fdae2bb 100644 --- a/.github/workflows/gitguardian.yml +++ b/.github/workflows/gitguardian.yml @@ -2,7 +2,7 @@ name: GitGuardian Scan on: push: - branches: + branches: - main pull_request: branches: @@ -19,6 +19,6 @@ jobs: - name: Run GitGuardian ggshield scan uses: GitGuardian/ggshield-action@v1 with: - args: scan path --exit-zero . + args: secret scan path --exit-zero . env: GITGUARDIAN_API_KEY: ${{ secrets.GITGUARDIAN_API_KEY }} From da6d3fde5d1436e78e30d732e35d63a79738e34a Mon Sep 17 00:00:00 2001 From: meleksabit Date: Wed, 11 Sep 2024 17:10:09 +0300 Subject: [PATCH 09/19] edit Git Guardian workflow --- .github/workflows/gitguardian.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gitguardian.yml b/.github/workflows/gitguardian.yml index fdae2bb..ec8a9b5 100644 --- a/.github/workflows/gitguardian.yml +++ b/.github/workflows/gitguardian.yml @@ -19,6 +19,6 @@ jobs: - name: Run GitGuardian ggshield scan uses: GitGuardian/ggshield-action@v1 with: - args: secret scan path --exit-zero . + args: ggshield secret scan path --exit-zero . env: GITGUARDIAN_API_KEY: ${{ secrets.GITGUARDIAN_API_KEY }} From e436b3fac85786f43e2567a6086c6567082dce73 Mon Sep 17 00:00:00 2001 From: meleksabit Date: Wed, 11 Sep 2024 17:12:14 +0300 Subject: [PATCH 10/19] edit Git Guardian workflow --- .github/workflows/gitguardian.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gitguardian.yml b/.github/workflows/gitguardian.yml index ec8a9b5..6d45a70 100644 --- a/.github/workflows/gitguardian.yml +++ b/.github/workflows/gitguardian.yml @@ -19,6 +19,6 @@ jobs: - name: Run GitGuardian ggshield scan uses: GitGuardian/ggshield-action@v1 with: - args: ggshield secret scan path --exit-zero . + args: ggshield secret scan -h env: GITGUARDIAN_API_KEY: ${{ secrets.GITGUARDIAN_API_KEY }} From caf63b1091835da3421ad6a9b3d6cc3bb4516cca Mon Sep 17 00:00:00 2001 From: meleksabit Date: Wed, 11 Sep 2024 17:15:16 +0300 Subject: [PATCH 11/19] edit Git Guardian workflow --- .github/workflows/gitguardian.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gitguardian.yml b/.github/workflows/gitguardian.yml index 6d45a70..37b542a 100644 --- a/.github/workflows/gitguardian.yml +++ b/.github/workflows/gitguardian.yml @@ -19,6 +19,6 @@ jobs: - name: Run GitGuardian ggshield scan uses: GitGuardian/ggshield-action@v1 with: - args: ggshield secret scan -h + args: path --exit-zero . env: GITGUARDIAN_API_KEY: ${{ secrets.GITGUARDIAN_API_KEY }} From 54081f3be62bfbcb2f5e7c12a8eb2799b9c408a5 Mon Sep 17 00:00:00 2001 From: meleksabit Date: Wed, 11 Sep 2024 17:20:26 +0300 Subject: [PATCH 12/19] edit Git Guardian workflow --- .github/workflows/gitguardian.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gitguardian.yml b/.github/workflows/gitguardian.yml index 37b542a..264a1f3 100644 --- a/.github/workflows/gitguardian.yml +++ b/.github/workflows/gitguardian.yml @@ -19,6 +19,6 @@ jobs: - name: Run GitGuardian ggshield scan uses: GitGuardian/ggshield-action@v1 with: - args: path --exit-zero . + args: path --exit-zero / env: GITGUARDIAN_API_KEY: ${{ secrets.GITGUARDIAN_API_KEY }} From 6a283a0e02a4bdf234042997ba138e4d8393e72e Mon Sep 17 00:00:00 2001 From: meleksabit Date: Wed, 11 Sep 2024 17:28:43 +0300 Subject: [PATCH 13/19] edit Git Guardian workflow --- .github/workflows/gitguardian.yml | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/.github/workflows/gitguardian.yml b/.github/workflows/gitguardian.yml index 264a1f3..c578c55 100644 --- a/.github/workflows/gitguardian.yml +++ b/.github/workflows/gitguardian.yml @@ -1,24 +1,22 @@ -name: GitGuardian Scan +name: GitGuardian scan -on: - push: - branches: - - main - pull_request: - branches: - - main +on: [push, pull_request] jobs: - ggshield: - name: GitGuardian Scan + scanning: + name: GitGuardian scan runs-on: ubuntu-latest steps: - - name: Checkout code + - name: Checkout uses: actions/checkout@v3 - - - name: Run GitGuardian ggshield scan - uses: GitGuardian/ggshield-action@v1 with: - args: path --exit-zero / + fetch-depth: 0 # fetch all history so multiple commits can be scanned + - name: GitGuardian scan + uses: GitGuardian/ggshield/actions/secret@v1.30.1 env: + GITHUB_PUSH_BEFORE_SHA: ${{ github.event.before }} + GITHUB_PUSH_BASE_SHA: ${{ github.event.base }} + GITHUB_PULL_BASE_SHA: ${{ github.event.pull_request.base.sha }} + GITHUB_DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} GITGUARDIAN_API_KEY: ${{ secrets.GITGUARDIAN_API_KEY }} + \ No newline at end of file From 1392fd14e8e01a32780601d6571dfcd4a4666b07 Mon Sep 17 00:00:00 2001 From: meleksabit Date: Wed, 11 Sep 2024 17:33:19 +0300 Subject: [PATCH 14/19] edit Git Guardian workflow --- .github/workflows/gitguardian.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/gitguardian.yml b/.github/workflows/gitguardian.yml index c578c55..268fcf7 100644 --- a/.github/workflows/gitguardian.yml +++ b/.github/workflows/gitguardian.yml @@ -12,11 +12,10 @@ jobs: with: fetch-depth: 0 # fetch all history so multiple commits can be scanned - name: GitGuardian scan - uses: GitGuardian/ggshield/actions/secret@v1.30.1 + uses: GitGuardian/ggshield/actions/secret@v1.31.1 env: GITHUB_PUSH_BEFORE_SHA: ${{ github.event.before }} GITHUB_PUSH_BASE_SHA: ${{ github.event.base }} GITHUB_PULL_BASE_SHA: ${{ github.event.pull_request.base.sha }} GITHUB_DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} GITGUARDIAN_API_KEY: ${{ secrets.GITGUARDIAN_API_KEY }} - \ No newline at end of file From 7b1f5a0144ded3747b59688bc788d2b4db043972 Mon Sep 17 00:00:00 2001 From: meleksabit Date: Wed, 11 Sep 2024 17:35:08 +0300 Subject: [PATCH 15/19] edit Git Guardian workflow --- .github/workflows/gitguardian.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gitguardian.yml b/.github/workflows/gitguardian.yml index 268fcf7..4133189 100644 --- a/.github/workflows/gitguardian.yml +++ b/.github/workflows/gitguardian.yml @@ -12,7 +12,7 @@ jobs: with: fetch-depth: 0 # fetch all history so multiple commits can be scanned - name: GitGuardian scan - uses: GitGuardian/ggshield/actions/secret@v1.31.1 + uses: GitGuardian/ggshield/actions/secret@v1.31.0 env: GITHUB_PUSH_BEFORE_SHA: ${{ github.event.before }} GITHUB_PUSH_BASE_SHA: ${{ github.event.base }} From b047d2fc8a5846e891b182c813d22bf4c3aa0c43 Mon Sep 17 00:00:00 2001 From: meleksabit Date: Sat, 14 Sep 2024 22:31:39 +0300 Subject: [PATCH 16/19] edit README file --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index bd4cc3d..b83edb5 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ +# $\color{Cerulean}{Python\}$ $\color{Goldenrod}{Examples\}$ [![CodeQL](https://github.com/meleksabit/My-Python-Examples/actions/workflows/codeql.yml/badge.svg)](https://github.com/meleksabit/My-Python-Examples/actions/workflows/codeql.yml) [![Bandit](https://github.com/meleksabit/My-Python-Examples/actions/workflows/bandit.yml/badge.svg)](https://github.com/meleksabit/My-Python-Examples/actions/workflows/bandit.yml) [![DevSecOps Pipeline](https://github.com/meleksabit/My-Python-Examples/actions/workflows/devsecops-pipeline.yml/badge.svg)](https://github.com/meleksabit/My-Python-Examples/actions/workflows/devsecops-pipeline.yml) From aa79a35629c7e4c3d285e34ac530298bbe528732 Mon Sep 17 00:00:00 2001 From: meleksabit Date: Thu, 26 Sep 2024 14:53:40 +0300 Subject: [PATCH 17/19] edit DevSecOps pipeline --- .github/workflows/devsecops-pipeline.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/devsecops-pipeline.yml b/.github/workflows/devsecops-pipeline.yml index 6d1d69a..60a17ec 100644 --- a/.github/workflows/devsecops-pipeline.yml +++ b/.github/workflows/devsecops-pipeline.yml @@ -14,10 +14,10 @@ jobs: steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Set up Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v5 with: python-version: '3.x' From 0bf5315a158f9443e24543c059c3673bec01a571 Mon Sep 17 00:00:00 2001 From: meleksabit Date: Mon, 7 Oct 2024 03:43:40 +0300 Subject: [PATCH 18/19] edit release badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 69af1b6..6b94149 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![CodeQL](https://github.com/meleksabit/My-Python-Examples/actions/workflows/codeql.yml/badge.svg)](https://github.com/meleksabit/My-Python-Examples/actions/workflows/codeql.yml) [![Bandit](https://github.com/meleksabit/My-Python-Examples/actions/workflows/bandit.yml/badge.svg)](https://github.com/meleksabit/My-Python-Examples/actions/workflows/bandit.yml) [![DevSecOps Pipeline](https://github.com/meleksabit/My-Python-Examples/actions/workflows/devsecops-pipeline.yml/badge.svg)](https://github.com/meleksabit/My-Python-Examples/actions/workflows/devsecops-pipeline.yml) -![GitHub Release](https://img.shields.io/github/v/release/meleksabit/My-Python-Examples) +[![GitHub Release](https://img.shields.io/github/v/release/meleksabit/My-Python-Examples)](https://github.com/meleksabit/My-Python-Examples/releases) # 🏎️Tesla Example: ![Python](https://user-images.githubusercontent.com/32045473/153525858-85772918-62df-4f29-9316-ccc946eb5eab.png) ![Python2](https://user-images.githubusercontent.com/32045473/153525899-d11d6922-075d-416e-b88a-1c14d4f62815.png) From a297c87a5ba5721d6ce33cbad025f81f072f755c Mon Sep 17 00:00:00 2001 From: meleksabit Date: Tue, 8 Oct 2024 03:55:29 +0300 Subject: [PATCH 19/19] add .gitignore file --- .gitignore | 115 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 114 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index c6f9a44..544d019 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,114 @@ -.vscode/settings.json +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a Python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# Jupyter Notebook +.ipynb_checkpoints + +# PyCharm +.idea/ + +# VSCode +.vscode/ + +# MacOS specific files +.DS_Store + +# Windows specific files +Thumbs.db +ehthumbs.db +Desktop.ini + +# Virtual environments +venv/ +ENV/ +env/ +.venv/ +env.bak/ +env.bak.tar.gz + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/