Merge branch 'master' into DEVREL-98-include-open-api-specification-in-mintlify

This commit is contained in:
Andoni Alonso
2025-11-10 08:39:59 +01:00
committed by GitHub
90 changed files with 4438 additions and 334 deletions
+6
View File
@@ -15,9 +15,15 @@ All notable changes to the **Prowler API** are documented in this file.
- Support C5 compliance framework for the GCP provider [(#9097)](https://github.com/prowler-cloud/prowler/pull/9097)
- Support for Amazon Bedrock and OpenAI compatible providers in Lighthouse AI [(#8957)](https://github.com/prowler-cloud/prowler/pull/8957)
- OpenAPI schema integration with Mintlify documentation including compatibility fixes and dynamic server URL configuration
- Support for MongoDB Atlas provider [(#9167)](https://github.com/prowler-cloud/prowler/pull/9167)
---
## [1.14.2] (Prowler 5.13.2)
### Fixed
- Update unique constraint for `Provider` model to exclude soft-deleted entries, resolving duplicate errors when re-deleting providers.
## [1.14.1] (Prowler 5.13.1)
### Fixed
@@ -0,0 +1,32 @@
# Generated by Django 5.1.13 on 2025-11-05 08:37
from django.db import migrations
import api.db_utils
class Migration(migrations.Migration):
dependencies = [
("api", "0054_iac_provider"),
]
operations = [
migrations.AlterField(
model_name="provider",
name="provider",
field=api.db_utils.ProviderEnumField(
choices=[
("aws", "AWS"),
("azure", "Azure"),
("gcp", "GCP"),
("kubernetes", "Kubernetes"),
("m365", "M365"),
("github", "GitHub"),
("mongodbatlas", "MongoDB Atlas"),
("iac", "IaC"),
("oraclecloud", "Oracle Cloud Infrastructure"),
],
default="aws",
),
),
]
@@ -0,0 +1,24 @@
# Generated by Django 5.1.13 on 2025-11-06 09:20
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("api", "0055_mongodbatlas_provider"),
]
operations = [
migrations.RemoveConstraint(
model_name="provider",
name="unique_provider_uids",
),
migrations.AddConstraint(
model_name="provider",
constraint=models.UniqueConstraint(
condition=models.Q(("is_deleted", False)),
fields=("tenant_id", "provider", "uid"),
name="unique_provider_uids",
),
),
]
+12 -1
View File
@@ -284,6 +284,7 @@ class Provider(RowLevelSecurityProtectedModel):
KUBERNETES = "kubernetes", _("Kubernetes")
M365 = "m365", _("M365")
GITHUB = "github", _("GitHub")
MONGODBATLAS = "mongodbatlas", _("MongoDB Atlas")
IAC = "iac", _("IaC")
ORACLECLOUD = "oraclecloud", _("Oracle Cloud Infrastructure")
@@ -381,6 +382,15 @@ class Provider(RowLevelSecurityProtectedModel):
pointer="/data/attributes/uid",
)
@staticmethod
def validate_mongodbatlas_uid(value):
if not re.match(r"^[0-9a-fA-F]{24}$", value):
raise ModelValidationError(
detail="MongoDB Atlas organization ID must be a 24-character hexadecimal string.",
code="mongodbatlas-uid",
pointer="/data/attributes/uid",
)
id = models.UUIDField(primary_key=True, default=uuid4, editable=False)
inserted_at = models.DateTimeField(auto_now_add=True, editable=False)
updated_at = models.DateTimeField(auto_now=True, editable=False)
@@ -415,7 +425,8 @@ class Provider(RowLevelSecurityProtectedModel):
constraints = [
models.UniqueConstraint(
fields=("tenant_id", "provider", "uid", "is_deleted"),
fields=("tenant_id", "provider", "uid"),
condition=Q(is_deleted=False),
name="unique_provider_uids",
),
RowLevelSecurityConstraint(
+77 -3
View File
@@ -875,6 +875,7 @@ paths:
- azure
- gcp
- github
- mongodbatlas
- iac
- kubernetes
- m365
@@ -886,6 +887,7 @@ paths:
* `kubernetes` - Kubernetes
* `m365` - M365
* `github` - GitHub
* `mongodbatlas` - MongoDB Atlas
* `iac` - IaC
* `oraclecloud` - Oracle Cloud Infrastructure
- in: query
@@ -901,6 +903,7 @@ paths:
- gcp
- github
- iac
- mongodbatlas
- kubernetes
- m365
- oraclecloud
@@ -913,6 +916,7 @@ paths:
* `kubernetes` - Kubernetes
* `m365` - M365
* `github` - GitHub
* `mongodbatlas` - MongoDB Atlas
* `iac` - IaC
* `oraclecloud` - Oracle Cloud Infrastructure
explode: false
@@ -1410,6 +1414,7 @@ paths:
- azure
- gcp
- github
- mongodbatlas
- iac
- kubernetes
- m365
@@ -1421,6 +1426,7 @@ paths:
* `kubernetes` - Kubernetes
* `m365` - M365
* `github` - GitHub
* `mongodbatlas` - MongoDB Atlas
* `iac` - IaC
* `oraclecloud` - Oracle Cloud Infrastructure
- in: query
@@ -1436,6 +1442,7 @@ paths:
- gcp
- github
- iac
- mongodbatlas
- kubernetes
- m365
- oraclecloud
@@ -1448,6 +1455,7 @@ paths:
* `kubernetes` - Kubernetes
* `m365` - M365
* `github` - GitHub
* `mongodbatlas` - MongoDB Atlas
* `iac` - IaC
* `oraclecloud` - Oracle Cloud Infrastructure
explode: false
@@ -1853,6 +1861,7 @@ paths:
- azure
- gcp
- github
- mongodbatlas
- iac
- kubernetes
- m365
@@ -1864,6 +1873,7 @@ paths:
* `kubernetes` - Kubernetes
* `m365` - M365
* `github` - GitHub
* `mongodbatlas` - MongoDB Atlas
* `iac` - IaC
* `oraclecloud` - Oracle Cloud Infrastructure
- in: query
@@ -1879,6 +1889,7 @@ paths:
- gcp
- github
- iac
- mongodbatlas
- kubernetes
- m365
- oraclecloud
@@ -1891,6 +1902,7 @@ paths:
* `kubernetes` - Kubernetes
* `m365` - M365
* `github` - GitHub
* `mongodbatlas` - MongoDB Atlas
* `iac` - IaC
* `oraclecloud` - Oracle Cloud Infrastructure
explode: false
@@ -2294,6 +2306,7 @@ paths:
- azure
- gcp
- github
- mongodbatlas
- iac
- kubernetes
- m365
@@ -2305,6 +2318,7 @@ paths:
* `kubernetes` - Kubernetes
* `m365` - M365
* `github` - GitHub
* `mongodbatlas` - MongoDB Atlas
* `iac` - IaC
* `oraclecloud` - Oracle Cloud Infrastructure
- in: query
@@ -2320,6 +2334,7 @@ paths:
- gcp
- github
- iac
- mongodbatlas
- kubernetes
- m365
- oraclecloud
@@ -2332,6 +2347,7 @@ paths:
* `kubernetes` - Kubernetes
* `m365` - M365
* `github` - GitHub
* `mongodbatlas` - MongoDB Atlas
* `iac` - IaC
* `oraclecloud` - Oracle Cloud Infrastructure
explode: false
@@ -2723,6 +2739,7 @@ paths:
- azure
- gcp
- github
- mongodbatlas
- iac
- kubernetes
- m365
@@ -2734,6 +2751,7 @@ paths:
* `kubernetes` - Kubernetes
* `m365` - M365
* `github` - GitHub
* `mongodbatlas` - MongoDB Atlas
* `iac` - IaC
* `oraclecloud` - Oracle Cloud Infrastructure
- in: query
@@ -2749,6 +2767,7 @@ paths:
- gcp
- github
- iac
- mongodbatlas
- kubernetes
- m365
- oraclecloud
@@ -2761,6 +2780,7 @@ paths:
* `kubernetes` - Kubernetes
* `m365` - M365
* `github` - GitHub
* `mongodbatlas` - MongoDB Atlas
* `iac` - IaC
* `oraclecloud` - Oracle Cloud Infrastructure
explode: false
@@ -4556,6 +4576,7 @@ paths:
- azure
- gcp
- github
- mongodbatlas
- iac
- kubernetes
- m365
@@ -4567,6 +4588,7 @@ paths:
* `kubernetes` - Kubernetes
* `m365` - M365
* `github` - GitHub
* `mongodbatlas` - MongoDB Atlas
* `iac` - IaC
* `oraclecloud` - Oracle Cloud Infrastructure
- in: query
@@ -4582,6 +4604,7 @@ paths:
- gcp
- github
- iac
- mongodbatlas
- kubernetes
- m365
- oraclecloud
@@ -4594,6 +4617,7 @@ paths:
* `kubernetes` - Kubernetes
* `m365` - M365
* `github` - GitHub
* `mongodbatlas` - MongoDB Atlas
* `iac` - IaC
* `oraclecloud` - Oracle Cloud Infrastructure
explode: false
@@ -4741,6 +4765,7 @@ paths:
- azure
- gcp
- github
- mongodbatlas
- iac
- kubernetes
- m365
@@ -4752,6 +4777,7 @@ paths:
* `kubernetes` - Kubernetes
* `m365` - M365
* `github` - GitHub
* `mongodbatlas` - MongoDB Atlas
* `iac` - IaC
* `oraclecloud` - Oracle Cloud Infrastructure
- in: query
@@ -4767,6 +4793,7 @@ paths:
- gcp
- github
- iac
- mongodbatlas
- kubernetes
- m365
- oraclecloud
@@ -4779,6 +4806,7 @@ paths:
* `kubernetes` - Kubernetes
* `m365` - M365
* `github` - GitHub
* `mongodbatlas` - MongoDB Atlas
* `iac` - IaC
* `oraclecloud` - Oracle Cloud Infrastructure
explode: false
@@ -4992,6 +5020,7 @@ paths:
- azure
- gcp
- github
- mongodbatlas
- iac
- kubernetes
- m365
@@ -5003,6 +5032,7 @@ paths:
* `kubernetes` - Kubernetes
* `m365` - M365
* `github` - GitHub
* `mongodbatlas` - MongoDB Atlas
* `iac` - IaC
* `oraclecloud` - Oracle Cloud Infrastructure
- in: query
@@ -5018,6 +5048,7 @@ paths:
- gcp
- github
- iac
- mongodbatlas
- kubernetes
- m365
- oraclecloud
@@ -5030,6 +5061,7 @@ paths:
* `kubernetes` - Kubernetes
* `m365` - M365
* `github` - GitHub
* `mongodbatlas` - MongoDB Atlas
* `iac` - IaC
* `oraclecloud` - Oracle Cloud Infrastructure
explode: false
@@ -5723,6 +5755,7 @@ paths:
- azure
- gcp
- github
- mongodbatlas
- iac
- kubernetes
- m365
@@ -5734,6 +5767,7 @@ paths:
* `kubernetes` - Kubernetes
* `m365` - M365
* `github` - GitHub
* `mongodbatlas` - MongoDB Atlas
* `iac` - IaC
* `oraclecloud` - Oracle Cloud Infrastructure
- in: query
@@ -5749,6 +5783,7 @@ paths:
- gcp
- github
- iac
- mongodbatlas
- kubernetes
- m365
- oraclecloud
@@ -5762,6 +5797,7 @@ paths:
* `m365` - M365
* `github` - GitHub
* `iac` - IaC
* `mongodbatlas` - MongoDB Atlas
* `oraclecloud` - Oracle Cloud Infrastructure
explode: false
style: form
@@ -6418,6 +6454,7 @@ paths:
- azure
- gcp
- github
- mongodbatlas
- iac
- kubernetes
- m365
@@ -6429,6 +6466,7 @@ paths:
* `kubernetes` - Kubernetes
* `m365` - M365
* `github` - GitHub
* `mongodbatlas` - MongoDB Atlas
* `iac` - IaC
* `oraclecloud` - Oracle Cloud Infrastructure
- in: query
@@ -6444,6 +6482,7 @@ paths:
- gcp
- github
- iac
- mongodbatlas
- kubernetes
- m365
- oraclecloud
@@ -6456,6 +6495,7 @@ paths:
* `kubernetes` - Kubernetes
* `m365` - M365
* `github` - GitHub
* `mongodbatlas` - MongoDB Atlas
* `iac` - IaC
* `oraclecloud` - Oracle Cloud Infrastructure
explode: false
@@ -6791,6 +6831,7 @@ paths:
- azure
- gcp
- github
- mongodbatlas
- iac
- kubernetes
- m365
@@ -6802,6 +6843,7 @@ paths:
* `kubernetes` - Kubernetes
* `m365` - M365
* `github` - GitHub
* `mongodbatlas` - MongoDB Atlas
* `iac` - IaC
* `oraclecloud` - Oracle Cloud Infrastructure
- in: query
@@ -6817,6 +6859,7 @@ paths:
- gcp
- github
- iac
- mongodbatlas
- kubernetes
- m365
- oraclecloud
@@ -6829,6 +6872,7 @@ paths:
* `kubernetes` - Kubernetes
* `m365` - M365
* `github` - GitHub
* `mongodbatlas` - MongoDB Atlas
* `iac` - IaC
* `oraclecloud` - Oracle Cloud Infrastructure
explode: false
@@ -7065,6 +7109,7 @@ paths:
- azure
- gcp
- github
- mongodbatlas
- iac
- kubernetes
- m365
@@ -7076,6 +7121,7 @@ paths:
* `kubernetes` - Kubernetes
* `m365` - M365
* `github` - GitHub
* `mongodbatlas` - MongoDB Atlas
* `iac` - IaC
* `oraclecloud` - Oracle Cloud Infrastructure
- in: query
@@ -7091,6 +7137,7 @@ paths:
- gcp
- github
- iac
- mongodbatlas
- kubernetes
- m365
- oraclecloud
@@ -7103,6 +7150,7 @@ paths:
* `kubernetes` - Kubernetes
* `m365` - M365
* `github` - GitHub
* `mongodbatlas` - MongoDB Atlas
* `iac` - IaC
* `oraclecloud` - Oracle Cloud Infrastructure
explode: false
@@ -7345,6 +7393,7 @@ paths:
- azure
- gcp
- github
- mongodbatlas
- iac
- kubernetes
- m365
@@ -7356,6 +7405,7 @@ paths:
* `kubernetes` - Kubernetes
* `m365` - M365
* `github` - GitHub
* `mongodbatlas` - MongoDB Atlas
* `iac` - IaC
* `oraclecloud` - Oracle Cloud Infrastructure
- in: query
@@ -7371,6 +7421,7 @@ paths:
- gcp
- github
- iac
- mongodbatlas
- kubernetes
- m365
- oraclecloud
@@ -7383,6 +7434,7 @@ paths:
* `kubernetes` - Kubernetes
* `m365` - M365
* `github` - GitHub
* `mongodbatlas` - MongoDB Atlas
* `iac` - IaC
* `oraclecloud` - Oracle Cloud Infrastructure
explode: false
@@ -8188,6 +8240,7 @@ paths:
- azure
- gcp
- github
- mongodbatlas
- iac
- kubernetes
- m365
@@ -8199,6 +8252,7 @@ paths:
* `kubernetes` - Kubernetes
* `m365` - M365
* `github` - GitHub
* `mongodbatlas` - MongoDB Atlas
* `iac` - IaC
* `oraclecloud` - Oracle Cloud Infrastructure
- in: query
@@ -8214,6 +8268,7 @@ paths:
- gcp
- github
- iac
- mongodbatlas
- kubernetes
- m365
- oraclecloud
@@ -8226,6 +8281,7 @@ paths:
* `kubernetes` - Kubernetes
* `m365` - M365
* `github` - GitHub
* `mongodbatlas` - MongoDB Atlas
* `iac` - IaC
* `oraclecloud` - Oracle Cloud Infrastructure
explode: false
@@ -14251,7 +14307,7 @@ components:
type: string
description: GitHub OAuth App token for authentication.
required:
- oauth_app_token
- oauth_app_token
- type: object
title: GitHub App Credentials
properties:
@@ -14264,6 +14320,18 @@ components:
required:
- github_app_id
- github_app_key
- type: object
title: MongoDB Atlas API Key
properties:
atlas_public_key:
type: string
description: MongoDB Atlas API public key.
atlas_private_key:
type: string
description: MongoDB Atlas API private key.
required:
- atlas_public_key
- atlas_private_key
- type: object
title: IaC Repository Credentials
properties:
@@ -15290,6 +15358,7 @@ components:
- m365
- github
- iac
- mongodbatlas
- oraclecloud
type: string
description: |-
@@ -15300,6 +15369,7 @@ components:
* `m365` - M365
* `github` - GitHub
* `iac` - IaC
* `mongodbatlas` - MongoDB Atlas
* `oraclecloud` - Oracle Cloud Infrastructure
x-spec-enum-id: cfe6f885ff538a1a
uid:
@@ -15414,6 +15484,7 @@ components:
- m365
- github
- iac
- mongodbatlas
- oraclecloud
type: string
x-spec-enum-id: cfe6f885ff538a1a
@@ -15427,12 +15498,13 @@ components:
* `m365` - M365
* `github` - GitHub
* `iac` - IaC
* `mongodbatlas` - MongoDB Atlas
* `oraclecloud` - Oracle Cloud Infrastructure
uid:
type: string
title: Unique identifier for the provider, set by the provider
description: Unique identifier for the provider, set by the provider,
e.g. AWS account ID, Azure subscription ID, GCP project ID, etc.
e.g. AWS account ID, Azure subscription ID, GCP project ID, MongoDB Atlas organization ID, etc.
maxLength: 250
minLength: 3
required:
@@ -15472,6 +15544,7 @@ components:
- m365
- github
- iac
- mongodbatlas
- oraclecloud
type: string
x-spec-enum-id: cfe6f885ff538a1a
@@ -15485,13 +15558,14 @@ components:
* `m365` - M365
* `github` - GitHub
* `iac` - IaC
* `mongodbatlas` - MongoDB Atlas
* `oraclecloud` - Oracle Cloud Infrastructure
uid:
type: string
minLength: 3
title: Unique identifier for the provider, set by the provider
description: Unique identifier for the provider, set by the provider,
e.g. AWS account ID, Azure subscription ID, GCP project ID, etc.
e.g. AWS account ID, Azure subscription ID, GCP project ID, MongoDB Atlas organization ID, etc.
maxLength: 250
required:
- uid
+8
View File
@@ -20,8 +20,10 @@ from prowler.providers.aws.aws_provider import AwsProvider
from prowler.providers.aws.lib.security_hub.security_hub import SecurityHubConnection
from prowler.providers.azure.azure_provider import AzureProvider
from prowler.providers.gcp.gcp_provider import GcpProvider
from prowler.providers.github.github_provider import GithubProvider
from prowler.providers.kubernetes.kubernetes_provider import KubernetesProvider
from prowler.providers.m365.m365_provider import M365Provider
from prowler.providers.mongodbatlas.mongodbatlas_provider import MongodbatlasProvider
from prowler.providers.oraclecloud.oraclecloud_provider import OraclecloudProvider
@@ -109,6 +111,8 @@ class TestReturnProwlerProvider:
(Provider.ProviderChoices.AZURE.value, AzureProvider),
(Provider.ProviderChoices.KUBERNETES.value, KubernetesProvider),
(Provider.ProviderChoices.M365.value, M365Provider),
(Provider.ProviderChoices.GITHUB.value, GithubProvider),
(Provider.ProviderChoices.MONGODBATLAS.value, MongodbatlasProvider),
(Provider.ProviderChoices.ORACLECLOUD.value, OraclecloudProvider),
],
)
@@ -209,6 +213,10 @@ class TestGetProwlerProviderKwargs:
Provider.ProviderChoices.ORACLECLOUD.value,
{},
),
(
Provider.ProviderChoices.MONGODBATLAS.value,
{"atlas_organization_id": "provider_uid"},
),
],
)
def test_get_prowler_provider_kwargs(self, provider_type, expected_extra_kwargs):
+194 -7
View File
@@ -1153,6 +1153,11 @@ class TestProviderViewSet:
"uid": "https://gitlab.com/user/project",
"alias": "GitLab Repo",
},
{
"provider": "mongodbatlas",
"uid": "64b1d3c0e4b03b1234567890",
"alias": "Atlas Organization",
},
]
),
)
@@ -1166,6 +1171,161 @@ class TestProviderViewSet:
assert Provider.objects.get().uid == provider_json_payload["uid"]
assert Provider.objects.get().alias == provider_json_payload["alias"]
@pytest.mark.parametrize(
"provider_json_payload",
(
[
{"provider": "aws", "uid": "111111111111", "alias": "test"},
{"provider": "gcp", "uid": "a12322-test54321", "alias": "test"},
{
"provider": "kubernetes",
"uid": "kubernetes-test-123456789",
"alias": "test",
},
{
"provider": "kubernetes",
"uid": "arn:aws:eks:us-east-1:111122223333:cluster/test-cluster-long-name-123456789",
"alias": "EKS",
},
{
"provider": "kubernetes",
"uid": "gke_aaaa-dev_europe-test1_dev-aaaa-test-cluster-long-name-123456789",
"alias": "GKE",
},
{
"provider": "kubernetes",
"uid": "gke_project/cluster-name",
"alias": "GKE",
},
{
"provider": "kubernetes",
"uid": "admin@k8s-demo",
"alias": "test",
},
{
"provider": "azure",
"uid": "8851db6b-42e5-4533-aa9e-30a32d67e875",
"alias": "test",
},
{
"provider": "m365",
"uid": "TestingPro.onmicrosoft.com",
"alias": "test",
},
{
"provider": "m365",
"uid": "subdomain.domain.es",
"alias": "test",
},
{
"provider": "m365",
"uid": "microsoft.net",
"alias": "test",
},
{
"provider": "m365",
"uid": "subdomain1.subdomain2.subdomain3.subdomain4.domain.net",
"alias": "test",
},
{
"provider": "github",
"uid": "test-user",
"alias": "test",
},
{
"provider": "github",
"uid": "test-organization",
"alias": "GitHub Org",
},
{
"provider": "github",
"uid": "prowler-cloud",
"alias": "Prowler",
},
{
"provider": "github",
"uid": "microsoft",
"alias": "Microsoft",
},
{
"provider": "github",
"uid": "a12345678901234567890123456789012345678",
"alias": "Long Username",
},
]
),
)
@patch("api.v1.views.Task.objects.get")
@patch("api.v1.views.delete_provider_task.delay")
def test_providers_soft_delete(
self,
mock_delete_task,
mock_task_get,
authenticated_client,
provider_json_payload,
tasks_fixture,
):
# Mock the Celery task response
prowler_task = tasks_fixture[0]
task_mock = Mock()
task_mock.id = prowler_task.id
mock_delete_task.return_value = task_mock
mock_task_get.return_value = prowler_task
# 1.Create a provider
response = authenticated_client.post(
reverse("provider-list"), data=provider_json_payload, format="json"
)
assert response.status_code == status.HTTP_201_CREATED
assert Provider.objects.count() == 1
provider_id = response.json()["data"]["id"]
# 2. Soft delete the provider using the actual API endpoint
response = authenticated_client.delete(
reverse("provider-detail", kwargs={"pk": provider_id})
)
assert response.status_code == status.HTTP_202_ACCEPTED
assert Provider.objects.count() == 0
assert Provider.all_objects.count() == 1
mock_delete_task.assert_called_once_with(
provider_id=str(provider_id), tenant_id=ANY
)
# 3. Create a provider with the same UID should succeed (since the old one is soft deleted)
response = authenticated_client.post(
reverse("provider-list"), data=provider_json_payload, format="json"
)
assert response.status_code == status.HTTP_201_CREATED
assert Provider.objects.count() == 1
assert Provider.all_objects.count() == 2
provider_id = response.json()["data"]["id"]
# 4. Creating another provider with the same UID should fail (duplicate)
response = authenticated_client.post(
reverse("provider-list"), data=provider_json_payload, format="json"
)
assert response.status_code == status.HTTP_400_BAD_REQUEST
mock_delete_task.reset_mock()
mock_delete_task.return_value = task_mock
# 5. Delete the second provider
response = authenticated_client.delete(
reverse("provider-detail", kwargs={"pk": provider_id})
)
assert response.status_code == status.HTTP_202_ACCEPTED
assert Provider.objects.count() == 0
assert Provider.all_objects.count() == 2
# 6. Creating a provider with the same UID should succeed again
response = authenticated_client.post(
reverse("provider-list"), data=provider_json_payload, format="json"
)
assert response.status_code == status.HTTP_201_CREATED
assert Provider.objects.count() == 1
assert Provider.all_objects.count() == 3
@pytest.mark.parametrize(
"provider_json_payload, error_code, error_pointer",
(
@@ -1329,6 +1489,24 @@ class TestProviderViewSet:
"iac-uid",
"uid",
),
(
{
"provider": "mongodbatlas",
"uid": "64b1d3c0e4b03b123456789g",
"alias": "test",
},
"mongodbatlas-uid",
"uid",
),
(
{
"provider": "mongodbatlas",
"uid": "1234",
"alias": "test",
},
"mongodbatlas-uid",
"uid",
),
]
),
)
@@ -1502,22 +1680,22 @@ class TestProviderViewSet:
(
"uid.icontains",
"1",
6,
), # Updated: includes OCI provider with "1" in UID
7,
),
("alias", "aws_testing_1", 1),
("alias.icontains", "aws", 2),
("inserted_at", TODAY, 7), # Updated: 7 providers now (added OCI)
("inserted_at", TODAY, 8),
(
"inserted_at.gte",
"2024-01-01",
7,
), # Updated: 7 providers now (added OCI)
8,
),
("inserted_at.lte", "2024-01-01", 0),
(
"updated_at.gte",
"2024-01-01",
7,
), # Updated: 7 providers now (added OCI)
8,
),
("updated_at.lte", "2024-01-01", 0),
]
),
@@ -2057,6 +2235,15 @@ class TestProviderSecretViewSet:
"pass_phrase": "my-secure-passphrase",
},
),
# MongoDB Atlas credentials
(
Provider.ProviderChoices.MONGODBATLAS.value,
ProviderSecret.TypeChoices.STATIC,
{
"atlas_public_key": "public-key",
"atlas_private_key": "private-key",
},
),
],
)
def test_provider_secrets_create_valid(
+13 -3
View File
@@ -21,6 +21,7 @@ from prowler.providers.github.github_provider import GithubProvider
from prowler.providers.iac.iac_provider import IacProvider
from prowler.providers.kubernetes.kubernetes_provider import KubernetesProvider
from prowler.providers.m365.m365_provider import M365Provider
from prowler.providers.mongodbatlas.mongodbatlas_provider import MongodbatlasProvider
from prowler.providers.oraclecloud.oraclecloud_provider import OraclecloudProvider
@@ -70,6 +71,7 @@ def return_prowler_provider(
| IacProvider
| KubernetesProvider
| M365Provider
| MongodbatlasProvider
| OraclecloudProvider
]:
"""Return the Prowler provider class based on the given provider type.
@@ -78,7 +80,7 @@ def return_prowler_provider(
provider (Provider): The provider object containing the provider type and associated secrets.
Returns:
AwsProvider | AzureProvider | GcpProvider | GithubProvider | IacProvider | KubernetesProvider | M365Provider | OraclecloudProvider: The corresponding provider class.
AwsProvider | AzureProvider | GcpProvider | GithubProvider | IacProvider | KubernetesProvider | M365Provider | OraclecloudProvider | MongodbatlasProvider: The corresponding provider class.
Raises:
ValueError: If the provider type specified in `provider.provider` is not supported.
@@ -96,6 +98,8 @@ def return_prowler_provider(
prowler_provider = M365Provider
case Provider.ProviderChoices.GITHUB.value:
prowler_provider = GithubProvider
case Provider.ProviderChoices.MONGODBATLAS.value:
prowler_provider = MongodbatlasProvider
case Provider.ProviderChoices.IAC.value:
prowler_provider = IacProvider
case Provider.ProviderChoices.ORACLECLOUD.value:
@@ -146,6 +150,11 @@ def get_prowler_provider_kwargs(
prowler_provider_kwargs["oauth_app_token"] = provider.secret.secret[
"access_token"
]
elif provider.provider == Provider.ProviderChoices.MONGODBATLAS.value:
prowler_provider_kwargs = {
**prowler_provider_kwargs,
"atlas_organization_id": provider.uid,
}
if mutelist_processor:
mutelist_content = mutelist_processor.configuration.get("Mutelist", {})
@@ -166,6 +175,7 @@ def initialize_prowler_provider(
| IacProvider
| KubernetesProvider
| M365Provider
| MongodbatlasProvider
| OraclecloudProvider
):
"""Initialize a Prowler provider instance based on the given provider type.
@@ -175,8 +185,8 @@ def initialize_prowler_provider(
mutelist_processor (Processor): The mutelist processor object containing the mutelist configuration.
Returns:
AwsProvider | AzureProvider | GcpProvider | GithubProvider | IacProvider | KubernetesProvider | M365Provider | OciProvider: An instance of the corresponding provider class
(`AwsProvider`, `AzureProvider`, `GcpProvider`, `GithubProvider`, `IacProvider`, `KubernetesProvider`, `M365Provider` or `OraclecloudProvider`) initialized with the
AwsProvider | AzureProvider | GcpProvider | GithubProvider | IacProvider | KubernetesProvider | M365Provider | OraclecloudProvider | MongodbatlasProvider: An instance of the corresponding provider class
(`AwsProvider`, `AzureProvider`, `GcpProvider`, `GithubProvider`, `IacProvider`, `KubernetesProvider`, `M365Provider`, `OraclecloudProvider` or `MongodbatlasProvider`) initialized with the
provider's secrets.
"""
prowler_provider = return_prowler_provider(provider)
@@ -289,6 +289,21 @@ from rest_framework_json_api import serializers
},
"required": ["user", "fingerprint", "tenancy", "region"],
},
{
"type": "object",
"title": "MongoDB Atlas API Key",
"properties": {
"atlas_public_key": {
"type": "string",
"description": "MongoDB Atlas API public key.",
},
"atlas_private_key": {
"type": "string",
"description": "MongoDB Atlas API private key.",
},
},
"required": ["atlas_public_key", "atlas_private_key"],
},
]
}
)
+10
View File
@@ -1370,6 +1370,8 @@ class BaseWriteProviderSecretSerializer(BaseWriteSerializer):
serializer = M365ProviderSecret(data=secret)
elif provider_type == Provider.ProviderChoices.ORACLECLOUD.value:
serializer = OracleCloudProviderSecret(data=secret)
elif provider_type == Provider.ProviderChoices.MONGODBATLAS.value:
serializer = MongoDBAtlasProviderSecret(data=secret)
else:
raise serializers.ValidationError(
{"provider": f"Provider type not supported {provider_type}"}
@@ -1466,6 +1468,14 @@ class GCPServiceAccountProviderSecret(serializers.Serializer):
resource_name = "provider-secrets"
class MongoDBAtlasProviderSecret(serializers.Serializer):
atlas_public_key = serializers.CharField()
atlas_private_key = serializers.CharField()
class Meta:
resource_name = "provider-secrets"
class KubernetesProviderSecret(serializers.Serializer):
kubeconfig_content = serializers.CharField()
+16 -1
View File
@@ -506,8 +506,23 @@ def providers_fixture(tenants_fixture):
alias="oci_testing",
tenant_id=tenant.id,
)
provider8 = Provider.objects.create(
provider="mongodbatlas",
uid="64b1d3c0e4b03b1234567890",
alias="mongodbatlas_testing",
tenant_id=tenant.id,
)
return provider1, provider2, provider3, provider4, provider5, provider6, provider7
return (
provider1,
provider2,
provider3,
provider4,
provider5,
provider6,
provider7,
provider8,
)
@pytest.fixture