[rp-reporter] Add Dockerfile

Add possibility to define extra tags when uploading the job

```
rp-reporter report-job <job-url> --tag mosk_version:mosk-25.2 --tag bm:432
```

Related-Prod: PRODX-53829

Change-Id: I3ff1e3c1dc5eda2b6680b957502216417c66b180
diff --git a/rp_reporter/.dockerignore b/rp_reporter/.dockerignore
new file mode 100644
index 0000000..fc4afb2
--- /dev/null
+++ b/rp_reporter/.dockerignore
@@ -0,0 +1,46 @@
+# Python cache
+__pycache__/
+*.pyc
+*.pyo
+*.pyd
+
+# Distribution / packaging
+*.egg-info/
+*.egg
+.eggs/
+build/
+dist/
+
+# Virtual environments
+.venv/
+venv/
+
+# Jupyter notebooks checkpoints
+.ipynb_checkpoints/
+
+# Logs
+*.log
+
+# Unit test / coverage reports
+.coverage
+.coverage.*
+.cache
+.pytest_cache/
+htmlcov/
+
+# IDE / editor settings
+.vscode/
+.idea/
+*.swp
+
+# Git & version control
+.git
+.gitignore
+
+# Environment variables / secrets
+.env
+*.env
+
+# Docker itself
+Dockerfile
+.dockerignore
\ No newline at end of file
diff --git a/rp_reporter/Dockerfile b/rp_reporter/Dockerfile
new file mode 100644
index 0000000..450bfec
--- /dev/null
+++ b/rp_reporter/Dockerfile
@@ -0,0 +1,9 @@
+FROM python:3.12-slim
+
+COPY . /var/lib/rp_reporter/
+WORKDIR /var/lib/rp_reporter/
+
+RUN apt-get update \
+    && apt-get install -y --no-install-recommends git
+
+RUN pip install --no-cache-dir .
diff --git a/rp_reporter/pyproject.toml b/rp_reporter/pyproject.toml
new file mode 100644
index 0000000..8cf3256
--- /dev/null
+++ b/rp_reporter/pyproject.toml
@@ -0,0 +1,3 @@
+[build-system]
+requires = ["setuptools>=61.0"]
+build-backend = "setuptools.build_meta"
\ No newline at end of file
diff --git a/rp_reporter/rp_reporter/batch_reporter.py b/rp_reporter/rp_reporter/batch_reporter.py
index 4ee723c..461437d 100755
--- a/rp_reporter/rp_reporter/batch_reporter.py
+++ b/rp_reporter/rp_reporter/batch_reporter.py
@@ -2,6 +2,7 @@
 import random
 
 import click
+import ipdb
 import jenkins_jinny.main as jj
 import jmespath
 import itertools
@@ -72,13 +73,14 @@
         self.job_status = None
         self.job_number = None
         self.job_url = None
+        self.rp_url = None
 
     @property
     def job_link(self):
         return f"[#{self.job_number} {self.job_status}]({self.job_url}) "
 
     def add_test_result(
-        self, test_name=None, testrail_url=None, rp_url=None, statistics=None
+        self, test_name:str=None, testrail_url:str=None, rp_url:str=None, statistics:str=None
     ):
         testrail_msg = f"[TestRailURL]({testrail_url})" if testrail_url else ""
         self.rp_url = rp_url
@@ -236,7 +238,9 @@
 
 
 def upload_job(
-    job: str | jj.Build, suite_per_job: bool = False, tags: Optional[dict] = None
+        job: str | jj.Build,
+        suite_per_job: bool = False,
+        tags: Optional[dict] = None
 ):
     if isinstance(job, str):
         job = jj.Build(job)
@@ -245,7 +249,8 @@
 
     print(f"│˶˙ᵕ˙˶)꜆ I take {job}")
 
-    tags.update(get_tags(job))
+    run_tags = dict()
+    run_tags.update(get_tags(job))
 
     reporter = Reporter()
     description = Description()
@@ -259,11 +264,11 @@
     description.job_url = job.url
 
     if suite_per_job:
-        tags["jenkins_job"] = job.number
+        run_tags["jenkins_job"] = job.number
         launch_id = rp_client.start_launch(
             name=job.name,
             start_time=timestamp(),
-            attributes=tags,
+            attributes=run_tags,
             description=f"Deployed job {job.url} by {job.triggered_by}",
         )
         if not rp_client.get_launch_info():
@@ -301,23 +306,24 @@
         match child.name:
             case "deploy-openstack-k8s-env":
                 if base_ubuntu := job.param.HEAT_BASE_IMAGE_DISTRO:
-                    tags["base_ubuntu"] = base_ubuntu
+                    run_tags["base_ubuntu"] = base_ubuntu
                 if masakari := job.param.INSTALL_MASAKARI:
-                    tags["masakari"] = masakari
+                    run_tags["masakari"] = masakari
                 if vault := job.param.INSTALL_VAULT:
-                    tags["vault"] = vault
+                    run_tags["vault"] = vault
                 if ceph := job.param.INSTALL_CEPH:
-                    tags["ceph"] = ceph
+                    run_tags["ceph"] = ceph
                 if telemetry := job.param.INSTALL_TELEMETRY:
-                    tags["telemetry"] = telemetry
+                    run_tags["telemetry"] = telemetry
 
                 osdpl_file = child.get_artifacts("deployed.yaml")
                 if not osdpl_file:
                     LOG.error(f"Can't find osdpl file in {job}")
                     continue
 
-                tags.update(get_tags_from_osdpl(osdpl_file))
-                rp_client.update_test_item(attributes=tags, item_uuid=launch_id)
+                run_tags.update(get_tags_from_osdpl(osdpl_file))
+                rp_client.update_test_item(attributes=run_tags,
+                                           item_uuid=launch_id)
                 description.rockoon_version = tags.get("rockoon_version")
 
             case "tempest-runner-k8s":
@@ -356,22 +362,19 @@
 
             case "oscore-si-tests-runner-k8s":
                 title = "SI tests"
-                if test_results_files := child.get_link_from_description("si_test_report.xml"):
-                    test_results_files = test_results_files[0]
+                test_results_files = child.get_link_from_description("si_test_report.xml")
                 if not test_results_files:
                     LOG.error(f"Can't found 'si_test_report.xml' in {child.url}")
 
             case "oscore-functional-tests-runner":
                 title = "Rockoon Functional"
-                if test_results_files := child.get_link_from_description("si_test_report.xml"):
-                    test_results_files = test_results_files[0]
+                test_results_files = child.get_link_from_description("si_test_report.xml")
                 if not test_results_files:
                     LOG.error(f"Can't found 'si_test_report.xml' in {child.url}")
 
             case "oscore-perf-analyzer-tests-runner":
                 title = "Performance tests"
-                if test_results_files := child.get_link_from_description("si_test_report.xml"):
-                    test_results_files = test_results_files[0]
+                test_results_files = child.get_link_from_description("si_test_report.xml")
                 if not test_results_files:
                     LOG.error(f"Can't found 'si_test_report.xml' in {child.url}")
 
@@ -383,8 +386,8 @@
                     LOG.error(
                         f"Can't found 'test_check_downtime_statistic_result.xml' in {child.url}"
                     )
-                test_results_files = (f"{artifactory_url}/artifacts/"
-                                     f"test_check_downtime_statistic_result.xml")
+                test_results_files = [f"{artifactory_url}/artifacts/"
+                                     f"test_check_downtime_statistic_result.xml"]
 
             case "collect-openstack-kaas-artifacts":
                 artifactory_url = child.description.split("url: ")[-1]
@@ -400,9 +403,8 @@
         if not test_results_files:
             # We can iterate by child jobs which don't contain any reports
             continue
-        testrail_url = [
-            url for url in child.get_link_from_description() if "testrail.com" in url
-        ]
+        if testrail_url := child.get_link_from_description("testrail.com"):
+            testrail_url = testrail_url[0]
         rp_client.log(
             time=timestamp(),
             message=f"Found file to upload: {test_results_files}",
@@ -432,7 +434,7 @@
         )
         description.add_test_result(
             test_name=f"{title} {test_tags.get('test', '')} ",
-            testrail_url=testrail_url[0] if testrail_url else None,
+            testrail_url=testrail_url,
             rp_url=rp_client.get_launch_ui_url(),
             statistics=stats,
         )
@@ -441,6 +443,7 @@
             message=f"Reported with stats: {stats}",
         )
 
+    run_tags.update(tags)
     rp_client.log(
         time=timestamp(),
         message="Reporting completed",
@@ -449,7 +452,7 @@
         report_url = rp_client.get_launch_ui_url()
         rp_client.finish_launch(
             end_time=timestamp(),
-            attributes=tags,
+            attributes=run_tags,
             description=str(description)
             + f"\nPod Logs {artifactory_url}/pod-logs.tar.gz",
         )
@@ -481,8 +484,18 @@
 
 @cli.command()
 @click.argument("job_url")
-def report_job(job_url):
-    upload_job(job_url, suite_per_job=True)
+@click.option("--tag", 'tags', multiple=True, default=[],
+              help="Add/override tag for testRun. "
+                   "Use a semicolon as a delimiter --tag version:25.1")
+def report_job(job_url, tags: List[str]):
+    tags_dict = dict()
+    for tag in tags:
+        k, v = tag.split(":", 1)
+        tags_dict[k] = v
+
+    upload_job(job=job_url,
+               tags=tags_dict,
+               suite_per_job=True)
 
 
 @cli.command()
diff --git a/rp_reporter/setup.cfg b/rp_reporter/setup.cfg
index 1d0da97..d86c76b 100644
--- a/rp_reporter/setup.cfg
+++ b/rp_reporter/setup.cfg
@@ -5,19 +5,24 @@
 license = Apache Software License
 author = mirantis
 author_email = harhipova@mirantis.com
-[global]
-setup-hooks = pbr.hooks.setup_hook
+version = 1.0.0
+
 [files]
 packages = rp_reporter
+
 [options]
 install_requires =
     xunitparser
     reportportal-client>=5.6.2
     PyYAML
     wget
-    jenkins-jinny @ git+https://github.com/annkapul/jenkins-jinny.git
+    jenkins-jinny[minimal] @ git+https://github.com/annkapul/jenkins-jinny.git
 
 [extras]
 test =
     flake8<3.8
     black
+
+[options.entry_points]
+console_scripts =
+    rp-reporter = rp_reporter.batch_reporter:cli
diff --git a/rp_reporter/setup.py b/rp_reporter/setup.py
deleted file mode 100644
index 89441e5..0000000
--- a/rp_reporter/setup.py
+++ /dev/null
@@ -1,14 +0,0 @@
-from setuptools import setup, find_packages
-
-setup(
-    name="rp-reporter",
-    setup_requires=['pbr==5.6.0'],
-    pbr=True,
-    packages=find_packages(),
-    python_requires=">=3.8",
-    entry_points={
-        "console_scripts": [
-            "rp-reporter=rp_reporter.batch_reporter:cli",
-        ],
-    },
-)
\ No newline at end of file