Merge branch 'staging' into environment-role-creation
This commit is contained in:
@@ -2,6 +2,8 @@ import json
|
||||
from unittest.mock import Mock, patch
|
||||
from uuid import uuid4
|
||||
|
||||
import pendulum
|
||||
import pydantic
|
||||
import pytest
|
||||
from tests.factories import ApplicationFactory, EnvironmentFactory
|
||||
from tests.mock_azure import AUTH_CREDENTIALS, mock_azure
|
||||
@@ -20,10 +22,16 @@ from atst.domain.csp.cloud.models import (
|
||||
BillingProfileTenantAccessCSPResult,
|
||||
BillingProfileVerificationCSPPayload,
|
||||
BillingProfileVerificationCSPResult,
|
||||
CostManagementQueryCSPResult,
|
||||
EnvironmentCSPPayload,
|
||||
EnvironmentCSPResult,
|
||||
PrincipalAdminRoleCSPPayload,
|
||||
PrincipalAdminRoleCSPResult,
|
||||
ProductPurchaseCSPPayload,
|
||||
ProductPurchaseCSPResult,
|
||||
ProductPurchaseVerificationCSPPayload,
|
||||
ProductPurchaseVerificationCSPResult,
|
||||
ReportingCSPPayload,
|
||||
SubscriptionCreationCSPPayload,
|
||||
SubscriptionCreationCSPResult,
|
||||
SubscriptionVerificationCSPPayload,
|
||||
@@ -44,7 +52,10 @@ from atst.domain.csp.cloud.models import (
|
||||
TenantPrincipalCSPResult,
|
||||
TenantPrincipalOwnershipCSPPayload,
|
||||
TenantPrincipalOwnershipCSPResult,
|
||||
UserCSPPayload,
|
||||
UserRoleCSPPayload,
|
||||
)
|
||||
from atst.domain.csp.cloud.exceptions import UserProvisioningException
|
||||
|
||||
BILLING_ACCOUNT_NAME = "52865e4c-52e8-5a6c-da6b-c58f0814f06f:7ea5de9d-b8ce-4901-b1c5-d864320c7b03_2019-05-31"
|
||||
|
||||
@@ -57,12 +68,14 @@ def mock_management_group_create(mock_azure, spec_dict):
|
||||
|
||||
def test_create_environment_succeeds(mock_azure: AzureCloudProvider):
|
||||
environment = EnvironmentFactory.create()
|
||||
|
||||
mock_management_group_create(mock_azure, {"id": "Test Id"})
|
||||
|
||||
result = mock_azure.create_environment(
|
||||
AUTH_CREDENTIALS, environment.creator, environment
|
||||
mock_azure = mock_get_secret(mock_azure)
|
||||
|
||||
payload = EnvironmentCSPPayload(
|
||||
tenant_id="1234", display_name=environment.name, parent_id=str(uuid4())
|
||||
)
|
||||
result = mock_azure.create_environment(payload)
|
||||
|
||||
assert result.id == "Test Id"
|
||||
|
||||
@@ -97,20 +110,6 @@ def test_create_application_succeeds(mock_azure: AzureCloudProvider):
|
||||
assert result.id == "Test Id"
|
||||
|
||||
|
||||
def test_create_atat_admin_user_succeeds(mock_azure: AzureCloudProvider):
|
||||
environment_id = str(uuid4())
|
||||
|
||||
csp_user_id = str(uuid4)
|
||||
|
||||
mock_azure.sdk.graphrbac.GraphRbacManagementClient.return_value.service_principals.create.return_value.object_id = (
|
||||
csp_user_id
|
||||
)
|
||||
|
||||
result = mock_azure.create_atat_admin_user(AUTH_CREDENTIALS, environment_id)
|
||||
|
||||
assert result.get("csp_user_id") == csp_user_id
|
||||
|
||||
|
||||
def test_create_policy_definition_succeeds(mock_azure: AzureCloudProvider):
|
||||
subscription_id = str(uuid4())
|
||||
management_group_id = str(uuid4())
|
||||
@@ -162,6 +161,27 @@ def test_create_tenant(mock_azure: AzureCloudProvider):
|
||||
assert body.tenant_id == "60ff9d34-82bf-4f21-b565-308ef0533435"
|
||||
|
||||
|
||||
def test_create_tenant_fails(mock_azure: AzureCloudProvider):
|
||||
mock_result = Mock()
|
||||
mock_result.json.return_value = {"error": "body"}
|
||||
mock_result.status_code = 403
|
||||
mock_azure.sdk.requests.post.return_value = mock_result
|
||||
payload = TenantCSPPayload(
|
||||
**dict(
|
||||
user_id="admin",
|
||||
password="JediJan13$coot", # pragma: allowlist secret
|
||||
domain_name="jediccpospawnedtenant2",
|
||||
first_name="Tedry",
|
||||
last_name="Tenet",
|
||||
country_code="US",
|
||||
password_recovery_email_address="thomas@promptworks.com",
|
||||
)
|
||||
)
|
||||
mock_azure = mock_get_secret(mock_azure)
|
||||
result = mock_azure.create_tenant(payload)
|
||||
assert result.get("status") == "error"
|
||||
|
||||
|
||||
def test_create_billing_profile_creation(mock_azure: AzureCloudProvider):
|
||||
mock_azure.sdk.adal.AuthenticationContext.return_value.context.acquire_token_with_client_credentials.return_value = {
|
||||
"accessToken": "TOKEN"
|
||||
@@ -573,10 +593,10 @@ def test_create_tenant_principal_credential(mock_azure: AzureCloudProvider):
|
||||
def test_create_admin_role_definition(mock_azure: AzureCloudProvider):
|
||||
with patch.object(
|
||||
AzureCloudProvider,
|
||||
"_get_elevated_management_token",
|
||||
wraps=mock_azure._get_elevated_management_token,
|
||||
) as get_elevated_management_token:
|
||||
get_elevated_management_token.return_value = "my fake token"
|
||||
"_get_tenant_admin_token",
|
||||
wraps=mock_azure._get_tenant_admin_token,
|
||||
) as get_tenant_admin_token:
|
||||
get_tenant_admin_token.return_value = "my fake token"
|
||||
|
||||
mock_result = Mock()
|
||||
mock_result.ok = True
|
||||
@@ -657,6 +677,35 @@ def test_create_tenant_principal_ownership(mock_azure: AzureCloudProvider):
|
||||
assert result.principal_owner_assignment_id == "id"
|
||||
|
||||
|
||||
def test_create_principal_admin_role(mock_azure: AzureCloudProvider):
|
||||
with patch.object(
|
||||
AzureCloudProvider,
|
||||
"_get_tenant_admin_token",
|
||||
wraps=mock_azure._get_tenant_admin_token,
|
||||
) as get_tenant_admin_token:
|
||||
get_tenant_admin_token.return_value = "my fake token"
|
||||
|
||||
mock_result = Mock()
|
||||
mock_result.ok = True
|
||||
mock_result.json.return_value = {"id": "id"}
|
||||
|
||||
mock_azure.sdk.requests.post.return_value = mock_result
|
||||
|
||||
payload = PrincipalAdminRoleCSPPayload(
|
||||
**{
|
||||
"tenant_id": uuid4().hex,
|
||||
"principal_id": "6d2d2d6c-a6d6-41e1-8bb1-73d11475f8f4",
|
||||
"admin_role_def_id": uuid4().hex,
|
||||
}
|
||||
)
|
||||
|
||||
result: PrincipalAdminRoleCSPResult = mock_azure.create_principal_admin_role(
|
||||
payload
|
||||
)
|
||||
|
||||
assert result.principal_assignment_id == "id"
|
||||
|
||||
|
||||
def test_create_subscription_creation(mock_azure: AzureCloudProvider):
|
||||
with patch.object(
|
||||
AzureCloudProvider,
|
||||
@@ -718,3 +767,224 @@ def test_create_subscription_verification(mock_azure: AzureCloudProvider):
|
||||
payload
|
||||
)
|
||||
assert result.subscription_id == "60fbbb72-0516-4253-ab18-c92432ba3230"
|
||||
|
||||
|
||||
def test_get_reporting_data(mock_azure: AzureCloudProvider):
|
||||
mock_result = Mock()
|
||||
mock_result.json.return_value = {
|
||||
"eTag": None,
|
||||
"id": "providers/Microsoft.Billing/billingAccounts/52865e4c-52e8-5a6c-da6b-c58f0814f06f:7ea5de9d-b8ce-4901-b1c5-d864320c7b03_2019-05-31/billingProfiles/XQDJ-6LB4-BG7-TGB/invoiceSections/P73M-XC7J-PJA-TGB/providers/Microsoft.CostManagement/query/e82d0cda-2ffb-4476-a98a-425c83c216f9",
|
||||
"location": None,
|
||||
"name": "e82d0cda-2ffb-4476-a98a-425c83c216f9",
|
||||
"properties": {
|
||||
"columns": [
|
||||
{"name": "PreTaxCost", "type": "Number"},
|
||||
{"name": "UsageDate", "type": "Number"},
|
||||
{"name": "InvoiceId", "type": "String"},
|
||||
{"name": "Currency", "type": "String"},
|
||||
],
|
||||
"nextLink": None,
|
||||
"rows": [],
|
||||
},
|
||||
"sku": None,
|
||||
"type": "Microsoft.CostManagement/query",
|
||||
}
|
||||
mock_result.ok = True
|
||||
mock_azure.sdk.requests.post.return_value = mock_result
|
||||
mock_azure = mock_get_secret(mock_azure)
|
||||
|
||||
# Subset of a profile's CSP data that we care about for reporting
|
||||
csp_data = {
|
||||
"tenant_id": "6d2d2d6c-a6d6-41e1-8bb1-73d11475f8f4",
|
||||
"billing_profile_properties": {
|
||||
"invoice_sections": [
|
||||
{
|
||||
"invoice_section_id": "providers/Microsoft.Billing/billingAccounts/52865e4c-52e8-5a6c-da6b-c58f0814f06f:7ea5de9d-b8ce-4901-b1c5-d864320c7b03_2019-05-31/billingProfiles/XQDJ-6LB4-BG7-TGB/invoiceSections/P73M-XC7J-PJA-TGB",
|
||||
}
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
data: CostManagementQueryCSPResult = mock_azure.get_reporting_data(
|
||||
ReportingCSPPayload(
|
||||
from_date=pendulum.now().subtract(years=1).add(days=1).format("YYYY-MM-DD"),
|
||||
to_date=pendulum.now().format("YYYY-MM-DD"),
|
||||
**csp_data,
|
||||
)
|
||||
)
|
||||
|
||||
assert isinstance(data, CostManagementQueryCSPResult)
|
||||
assert data.name == "e82d0cda-2ffb-4476-a98a-425c83c216f9"
|
||||
assert len(data.properties.columns) == 4
|
||||
|
||||
|
||||
def test_get_reporting_data_malformed_payload(mock_azure: AzureCloudProvider):
|
||||
mock_result = Mock()
|
||||
mock_result.ok = True
|
||||
mock_azure.sdk.requests.post.return_value = mock_result
|
||||
mock_azure = mock_get_secret(mock_azure)
|
||||
|
||||
# Malformed csp_data payloads that should throw pydantic validation errors
|
||||
index_error = {
|
||||
"tenant_id": "6d2d2d6c-a6d6-41e1-8bb1-73d11475f8f4",
|
||||
"billing_profile_properties": {"invoice_sections": [],},
|
||||
}
|
||||
key_error = {
|
||||
"tenant_id": "6d2d2d6c-a6d6-41e1-8bb1-73d11475f8f4",
|
||||
"billing_profile_properties": {"invoice_sections": [{}],},
|
||||
}
|
||||
|
||||
for malformed_payload in [key_error, index_error]:
|
||||
with pytest.raises(pydantic.ValidationError):
|
||||
assert mock_azure.get_reporting_data(
|
||||
ReportingCSPPayload(
|
||||
from_date="foo", to_date="bar", **malformed_payload,
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def test_get_secret(mock_azure: AzureCloudProvider):
|
||||
with patch.object(
|
||||
AzureCloudProvider,
|
||||
"_get_client_secret_credential_obj",
|
||||
wraps=mock_azure._get_client_secret_credential_obj,
|
||||
) as _get_client_secret_credential_obj:
|
||||
_get_client_secret_credential_obj.return_value = {}
|
||||
|
||||
mock_azure.sdk.secrets.SecretClient.return_value.get_secret.return_value.value = (
|
||||
"my secret"
|
||||
)
|
||||
|
||||
assert mock_azure.get_secret("secret key") == "my secret"
|
||||
|
||||
|
||||
def test_set_secret(mock_azure: AzureCloudProvider):
|
||||
with patch.object(
|
||||
AzureCloudProvider,
|
||||
"_get_client_secret_credential_obj",
|
||||
wraps=mock_azure._get_client_secret_credential_obj,
|
||||
) as _get_client_secret_credential_obj:
|
||||
_get_client_secret_credential_obj.return_value = {}
|
||||
|
||||
mock_azure.sdk.secrets.SecretClient.return_value.set_secret.return_value = (
|
||||
"my secret"
|
||||
)
|
||||
|
||||
assert mock_azure.set_secret("secret key", "secret_value") == "my secret"
|
||||
|
||||
|
||||
def test_create_active_directory_user(mock_azure: AzureCloudProvider):
|
||||
mock_result = Mock()
|
||||
mock_result.ok = True
|
||||
mock_result.json.return_value = {"id": "id"}
|
||||
mock_azure.sdk.requests.post.return_value = mock_result
|
||||
|
||||
payload = UserCSPPayload(
|
||||
tenant_id=uuid4().hex,
|
||||
display_name="Test Testerson",
|
||||
tenant_host_name="testtenant",
|
||||
email="test@testerson.test",
|
||||
password="asdfghjkl", # pragma: allowlist secret
|
||||
)
|
||||
|
||||
result = mock_azure._create_active_directory_user("token", payload)
|
||||
|
||||
assert result.id == "id"
|
||||
|
||||
|
||||
def test_update_active_directory_user_email(mock_azure: AzureCloudProvider):
|
||||
mock_result = Mock()
|
||||
mock_result.ok = True
|
||||
mock_azure.sdk.requests.patch.return_value = mock_result
|
||||
|
||||
payload = UserCSPPayload(
|
||||
tenant_id=uuid4().hex,
|
||||
display_name="Test Testerson",
|
||||
tenant_host_name="testtenant",
|
||||
email="test@testerson.test",
|
||||
password="asdfghjkl", # pragma: allowlist secret
|
||||
)
|
||||
|
||||
result = mock_azure._update_active_directory_user_email(
|
||||
"token", uuid4().hex, payload
|
||||
)
|
||||
|
||||
assert result
|
||||
|
||||
|
||||
def test_create_user(mock_azure: AzureCloudProvider):
|
||||
with patch.object(
|
||||
AzureCloudProvider,
|
||||
"_get_tenant_principal_token",
|
||||
wraps=mock_azure._get_tenant_principal_token,
|
||||
) as _get_tenant_principal_token:
|
||||
_get_tenant_principal_token.return_value = "token"
|
||||
|
||||
mock_result_create = Mock()
|
||||
mock_result_create.ok = True
|
||||
mock_result_create.json.return_value = {"id": "id"}
|
||||
mock_azure.sdk.requests.post.return_value = mock_result_create
|
||||
|
||||
mock_result_update = Mock()
|
||||
mock_result_update.ok = True
|
||||
mock_azure.sdk.requests.patch.return_value = mock_result_update
|
||||
|
||||
payload = UserCSPPayload(
|
||||
tenant_id=uuid4().hex,
|
||||
display_name="Test Testerson",
|
||||
tenant_host_name="testtenant",
|
||||
email="test@testerson.test",
|
||||
password="asdfghjkl", # pragma: allowlist secret
|
||||
)
|
||||
|
||||
result = mock_azure.create_user(payload)
|
||||
|
||||
assert result.id == "id"
|
||||
|
||||
|
||||
def test_create_user_role(mock_azure: AzureCloudProvider):
|
||||
with patch.object(
|
||||
AzureCloudProvider,
|
||||
"_get_tenant_principal_token",
|
||||
wraps=mock_azure._get_tenant_principal_token,
|
||||
) as _get_tenant_principal_token:
|
||||
_get_tenant_principal_token.return_value = "token"
|
||||
|
||||
mock_result_create = Mock()
|
||||
mock_result_create.ok = True
|
||||
mock_result_create.json.return_value = {"id": "id"}
|
||||
mock_azure.sdk.requests.put.return_value = mock_result_create
|
||||
|
||||
payload = UserRoleCSPPayload(
|
||||
tenant_id=uuid4().hex,
|
||||
user_object_id=str(uuid4()),
|
||||
management_group_id=str(uuid4()),
|
||||
role="owner",
|
||||
)
|
||||
|
||||
result = mock_azure.create_user_role(payload)
|
||||
|
||||
assert result.id == "id"
|
||||
|
||||
|
||||
def test_create_user_role_failure(mock_azure: AzureCloudProvider):
|
||||
with patch.object(
|
||||
AzureCloudProvider,
|
||||
"_get_tenant_principal_token",
|
||||
wraps=mock_azure._get_tenant_principal_token,
|
||||
) as _get_tenant_principal_token:
|
||||
_get_tenant_principal_token.return_value = "token"
|
||||
|
||||
mock_result_create = Mock()
|
||||
mock_result_create.ok = False
|
||||
mock_azure.sdk.requests.put.return_value = mock_result_create
|
||||
|
||||
payload = UserRoleCSPPayload(
|
||||
tenant_id=uuid4().hex,
|
||||
user_object_id=str(uuid4()),
|
||||
management_group_id=str(uuid4()),
|
||||
role="owner",
|
||||
)
|
||||
|
||||
with pytest.raises(UserProvisioningException):
|
||||
mock_azure.create_user_role(payload)
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import pytest
|
||||
|
||||
from atst.domain.csp import MockCloudProvider
|
||||
from atst.domain.csp.cloud.models import EnvironmentCSPPayload, EnvironmentCSPResult
|
||||
|
||||
from tests.factories import EnvironmentFactory, EnvironmentRoleFactory, UserFactory
|
||||
|
||||
@@ -14,20 +15,17 @@ def mock_csp():
|
||||
|
||||
def test_create_environment(mock_csp: MockCloudProvider):
|
||||
environment = EnvironmentFactory.create()
|
||||
user = UserFactory.create()
|
||||
environment_id = mock_csp.create_environment(CREDENTIALS, user, environment)
|
||||
assert isinstance(environment_id, str)
|
||||
|
||||
|
||||
def test_create_admin_user(mock_csp: MockCloudProvider):
|
||||
admin_user = mock_csp.create_atat_admin_user(CREDENTIALS, "env_id")
|
||||
assert isinstance(admin_user["id"], str)
|
||||
assert isinstance(admin_user["credentials"], dict)
|
||||
|
||||
|
||||
def test_create_environment_baseline(mock_csp: MockCloudProvider):
|
||||
baseline = mock_csp.create_atat_admin_user(CREDENTIALS, "env_id")
|
||||
assert isinstance(baseline, dict)
|
||||
environment.application.cloud_id = "parent_id"
|
||||
environment.application.portfolio.csp_data = {"tenant_id": "fake"}
|
||||
payload = EnvironmentCSPPayload(
|
||||
**dict(
|
||||
tenant_id=environment.application.portfolio.csp_data.get("tenant_id"),
|
||||
display_name=environment.name,
|
||||
parent_id=environment.application.cloud_id,
|
||||
)
|
||||
)
|
||||
result = mock_csp.create_environment(payload)
|
||||
assert isinstance(result, EnvironmentCSPResult)
|
||||
|
||||
|
||||
def test_create_or_update_user(mock_csp: MockCloudProvider):
|
||||
|
@@ -93,27 +93,25 @@ def test_disable_completed(application_role, environment):
|
||||
|
||||
def test_disable_checks_env_provisioning_status(session):
|
||||
environment = EnvironmentFactory.create()
|
||||
assert environment.is_pending
|
||||
assert not environment.cloud_id
|
||||
env_role1 = EnvironmentRoleFactory.create(environment=environment)
|
||||
env_role1 = EnvironmentRoles.disable(env_role1.id)
|
||||
assert env_role1.disabled
|
||||
|
||||
environment.cloud_id = "cloud-id"
|
||||
environment.root_user_info = {"credentials": "credentials"}
|
||||
session.add(environment)
|
||||
session.commit()
|
||||
session.refresh(environment)
|
||||
|
||||
assert not environment.is_pending
|
||||
assert environment.cloud_id
|
||||
env_role2 = EnvironmentRoleFactory.create(environment=environment)
|
||||
env_role2 = EnvironmentRoles.disable(env_role2.id)
|
||||
assert env_role2.disabled
|
||||
|
||||
|
||||
def test_disable_checks_env_role_provisioning_status():
|
||||
environment = EnvironmentFactory.create(
|
||||
cloud_id="cloud-id", root_user_info={"credentials": "credentials"}
|
||||
)
|
||||
environment = EnvironmentFactory.create(cloud_id="cloud-id")
|
||||
environment.application.portfolio.csp_data = {"tenant_id": uuid4().hex}
|
||||
env_role1 = EnvironmentRoleFactory.create(environment=environment)
|
||||
assert not env_role1.cloud_id
|
||||
env_role1 = EnvironmentRoles.disable(env_role1.id)
|
||||
|
@@ -1,5 +1,4 @@
|
||||
import pytest
|
||||
import pendulum
|
||||
from uuid import uuid4
|
||||
|
||||
from atst.domain.environments import Environments
|
||||
@@ -14,6 +13,7 @@ from tests.factories import (
|
||||
EnvironmentRoleFactory,
|
||||
ApplicationRoleFactory,
|
||||
)
|
||||
from tests.utils import EnvQueryTest
|
||||
|
||||
|
||||
def test_create_environments():
|
||||
@@ -119,40 +119,6 @@ def test_update_does_not_duplicate_names_within_application():
|
||||
Environments.update(dupe_env, name)
|
||||
|
||||
|
||||
class EnvQueryTest:
|
||||
@property
|
||||
def NOW(self):
|
||||
return pendulum.now()
|
||||
|
||||
@property
|
||||
def YESTERDAY(self):
|
||||
return self.NOW.subtract(days=1)
|
||||
|
||||
@property
|
||||
def TOMORROW(self):
|
||||
return self.NOW.add(days=1)
|
||||
|
||||
def create_portfolio_with_clins(self, start_and_end_dates, env_data=None):
|
||||
env_data = env_data or {}
|
||||
return PortfolioFactory.create(
|
||||
applications=[
|
||||
{
|
||||
"name": "Mos Eisley",
|
||||
"description": "Where Han shot first",
|
||||
"environments": [{"name": "thebar", **env_data}],
|
||||
}
|
||||
],
|
||||
task_orders=[
|
||||
{
|
||||
"create_clins": [
|
||||
{"start_date": start_date, "end_date": end_date}
|
||||
for (start_date, end_date) in start_and_end_dates
|
||||
]
|
||||
}
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
class TestGetEnvironmentsPendingCreate(EnvQueryTest):
|
||||
def test_with_expired_clins(self, session):
|
||||
self.create_portfolio_with_clins([(self.YESTERDAY, self.YESTERDAY)])
|
||||
@@ -168,37 +134,16 @@ class TestGetEnvironmentsPendingCreate(EnvQueryTest):
|
||||
self.create_portfolio_with_clins([(self.TOMORROW, self.TOMORROW)])
|
||||
assert len(Environments.get_environments_pending_creation(self.NOW)) == 0
|
||||
|
||||
def test_with_already_provisioned_app(self, session):
|
||||
self.create_portfolio_with_clins(
|
||||
[(self.YESTERDAY, self.TOMORROW)], app_data={"cloud_id": uuid4().hex}
|
||||
)
|
||||
assert len(Environments.get_environments_pending_creation(self.NOW)) == 1
|
||||
|
||||
def test_with_already_provisioned_env(self, session):
|
||||
self.create_portfolio_with_clins(
|
||||
[(self.YESTERDAY, self.TOMORROW)], env_data={"cloud_id": uuid4().hex}
|
||||
[(self.YESTERDAY, self.TOMORROW)],
|
||||
env_data={"cloud_id": uuid4().hex},
|
||||
app_data={"cloud_id": uuid4().hex},
|
||||
)
|
||||
assert len(Environments.get_environments_pending_creation(self.NOW)) == 0
|
||||
|
||||
|
||||
class TestGetEnvironmentsPendingAtatUserCreation(EnvQueryTest):
|
||||
def test_with_provisioned_environment(self):
|
||||
self.create_portfolio_with_clins(
|
||||
[(self.YESTERDAY, self.TOMORROW)],
|
||||
{"cloud_id": uuid4().hex, "root_user_info": {}},
|
||||
)
|
||||
assert (
|
||||
len(Environments.get_environments_pending_atat_user_creation(self.NOW)) == 0
|
||||
)
|
||||
|
||||
def test_with_unprovisioned_environment(self):
|
||||
self.create_portfolio_with_clins(
|
||||
[(self.YESTERDAY, self.TOMORROW)],
|
||||
{"cloud_id": uuid4().hex, "root_user_info": None},
|
||||
)
|
||||
assert (
|
||||
len(Environments.get_environments_pending_atat_user_creation(self.NOW)) == 1
|
||||
)
|
||||
|
||||
def test_with_unprovisioned_expired_clins_environment(self):
|
||||
self.create_portfolio_with_clins(
|
||||
[(self.YESTERDAY, self.YESTERDAY)],
|
||||
{"cloud_id": uuid4().hex, "root_user_info": None},
|
||||
)
|
||||
assert (
|
||||
len(Environments.get_environments_pending_atat_user_creation(self.NOW)) == 0
|
||||
)
|
||||
|
@@ -26,6 +26,7 @@ from tests.factories import (
|
||||
PortfolioStateMachineFactory,
|
||||
get_all_portfolio_permission_sets,
|
||||
)
|
||||
from tests.utils import EnvQueryTest
|
||||
|
||||
|
||||
@pytest.fixture(scope="function")
|
||||
@@ -263,10 +264,44 @@ def test_create_state_machine(portfolio):
|
||||
assert fsm
|
||||
|
||||
|
||||
def test_get_portfolios_pending_provisioning(session):
|
||||
for x in range(5):
|
||||
portfolio = PortfolioFactory.create()
|
||||
sm = PortfolioStateMachineFactory.create(portfolio=portfolio)
|
||||
if x == 2:
|
||||
sm.state = FSMStates.COMPLETED
|
||||
assert len(Portfolios.get_portfolios_pending_provisioning()) == 4
|
||||
class TestGetPortfoliosPendingCreate(EnvQueryTest):
|
||||
def test_finds_unstarted(self):
|
||||
for x in range(5):
|
||||
if x == 2:
|
||||
state = "COMPLETED"
|
||||
else:
|
||||
state = "UNSTARTED"
|
||||
self.create_portfolio_with_clins(
|
||||
[(self.YESTERDAY, self.TOMORROW)], state_machine_status=state
|
||||
)
|
||||
assert len(Portfolios.get_portfolios_pending_provisioning(self.NOW)) == 4
|
||||
|
||||
def test_finds_created(self):
|
||||
self.create_portfolio_with_clins(
|
||||
[(self.YESTERDAY, self.TOMORROW)], state_machine_status="TENANT_CREATED"
|
||||
)
|
||||
assert len(Portfolios.get_portfolios_pending_provisioning(self.NOW)) == 1
|
||||
|
||||
def test_does_not_find_failed(self):
|
||||
self.create_portfolio_with_clins(
|
||||
[(self.YESTERDAY, self.TOMORROW)], state_machine_status="TENANT_FAILED"
|
||||
)
|
||||
assert len(Portfolios.get_portfolios_pending_provisioning(self.NOW)) == 0
|
||||
|
||||
def test_with_expired_clins(self):
|
||||
self.create_portfolio_with_clins([(self.YESTERDAY, self.YESTERDAY)])
|
||||
assert len(Portfolios.get_portfolios_pending_provisioning(self.NOW)) == 0
|
||||
|
||||
def test_with_active_clins(self):
|
||||
portfolio = self.create_portfolio_with_clins([(self.YESTERDAY, self.TOMORROW)])
|
||||
Portfolios.get_portfolios_pending_provisioning(self.NOW) == [portfolio.id]
|
||||
|
||||
def test_with_future_clins(self):
|
||||
self.create_portfolio_with_clins([(self.TOMORROW, self.TOMORROW)])
|
||||
assert len(Portfolios.get_portfolios_pending_provisioning(self.NOW)) == 0
|
||||
|
||||
def test_with_already_provisioned_env(self):
|
||||
self.create_portfolio_with_clins(
|
||||
[(self.YESTERDAY, self.TOMORROW)], env_data={"cloud_id": uuid4().hex}
|
||||
)
|
||||
assert len(Portfolios.get_portfolios_pending_provisioning(self.NOW)) == 0
|
||||
|
@@ -51,28 +51,6 @@ def test_audit_event_for_environment_deletion(session):
|
||||
assert after
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"env_data,expected_status",
|
||||
[
|
||||
[
|
||||
{"cloud_id": None, "root_user_info": None},
|
||||
Environment.ProvisioningStatus.PENDING,
|
||||
],
|
||||
[
|
||||
{"cloud_id": 1, "root_user_info": None},
|
||||
Environment.ProvisioningStatus.PENDING,
|
||||
],
|
||||
[
|
||||
{"cloud_id": 1, "root_user_info": {}},
|
||||
Environment.ProvisioningStatus.COMPLETED,
|
||||
],
|
||||
],
|
||||
)
|
||||
def test_environment_provisioning_status(env_data, expected_status):
|
||||
environment = EnvironmentFactory.create(**env_data)
|
||||
assert environment.provisioning_status == expected_status
|
||||
|
||||
|
||||
def test_environment_roles_do_not_include_deleted():
|
||||
member_list = [
|
||||
{"role_name": CSPRole.ADMIN},
|
||||
|
@@ -14,7 +14,6 @@ from atst.jobs import (
|
||||
dispatch_create_application,
|
||||
dispatch_create_user,
|
||||
dispatch_create_environment_role,
|
||||
dispatch_create_atat_admin_user,
|
||||
dispatch_provision_portfolio,
|
||||
create_environment,
|
||||
do_create_user,
|
||||
@@ -22,7 +21,6 @@ from atst.jobs import (
|
||||
do_create_environment,
|
||||
do_create_environment_role,
|
||||
do_create_application,
|
||||
do_create_atat_admin_user,
|
||||
)
|
||||
from tests.factories import (
|
||||
EnvironmentFactory,
|
||||
@@ -97,6 +95,10 @@ tomorrow = now.add(days=1)
|
||||
|
||||
def test_create_environment_job(session, csp):
|
||||
environment = EnvironmentFactory.create()
|
||||
environment.application.cloud_id = "parentId"
|
||||
environment.application.portfolio.csp_data = {"tenant_id": "fake"}
|
||||
session.add(environment)
|
||||
session.commit()
|
||||
do_create_environment(csp, environment.id)
|
||||
session.refresh(environment)
|
||||
|
||||
@@ -152,19 +154,11 @@ def test_create_user_job(session, csp):
|
||||
assert app_role.cloud_id
|
||||
|
||||
|
||||
def test_create_atat_admin_user(csp, session):
|
||||
environment = EnvironmentFactory.create(cloud_id="something")
|
||||
do_create_atat_admin_user(csp, environment.id)
|
||||
session.refresh(environment)
|
||||
|
||||
assert environment.root_user_info
|
||||
|
||||
|
||||
def test_dispatch_create_environment(session, monkeypatch):
|
||||
# Given that I have a portfolio with an active CLIN and two environments,
|
||||
# one of which is deleted
|
||||
portfolio = PortfolioFactory.create(
|
||||
applications=[{"environments": [{}, {}]}],
|
||||
applications=[{"environments": [{}, {}], "cloud_id": uuid4().hex}],
|
||||
task_orders=[
|
||||
{
|
||||
"create_clins": [
|
||||
@@ -230,36 +224,9 @@ def test_dispatch_create_user(monkeypatch):
|
||||
mock.delay.assert_called_once_with(application_role_ids=[app_role.id])
|
||||
|
||||
|
||||
def test_dispatch_create_atat_admin_user(session, monkeypatch):
|
||||
portfolio = PortfolioFactory.create(
|
||||
applications=[
|
||||
{"environments": [{"cloud_id": uuid4().hex, "root_user_info": None}]}
|
||||
],
|
||||
task_orders=[
|
||||
{
|
||||
"create_clins": [
|
||||
{
|
||||
"start_date": pendulum.now().subtract(days=1),
|
||||
"end_date": pendulum.now().add(days=1),
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
)
|
||||
mock = Mock()
|
||||
monkeypatch.setattr("atst.jobs.create_atat_admin_user", mock)
|
||||
environment = portfolio.applications[0].environments[0]
|
||||
|
||||
dispatch_create_atat_admin_user.run()
|
||||
|
||||
mock.delay.assert_called_once_with(environment_id=environment.id)
|
||||
|
||||
|
||||
def test_create_environment_no_dupes(session, celery_app, celery_worker):
|
||||
portfolio = PortfolioFactory.create(
|
||||
applications=[
|
||||
{"environments": [{"cloud_id": uuid4().hex, "root_user_info": {}}]}
|
||||
],
|
||||
applications=[{"environments": [{"cloud_id": uuid4().hex}]}],
|
||||
task_orders=[
|
||||
{
|
||||
"create_clins": [
|
||||
@@ -289,9 +256,19 @@ def test_create_environment_no_dupes(session, celery_app, celery_worker):
|
||||
assert environment.claimed_until == None
|
||||
|
||||
|
||||
def test_dispatch_provision_portfolio(
|
||||
csp, session, portfolio, celery_app, celery_worker, monkeypatch
|
||||
):
|
||||
def test_dispatch_provision_portfolio(csp, monkeypatch):
|
||||
portfolio = PortfolioFactory.create(
|
||||
task_orders=[
|
||||
{
|
||||
"create_clins": [
|
||||
{
|
||||
"start_date": pendulum.now().subtract(days=1),
|
||||
"end_date": pendulum.now().add(days=1),
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
)
|
||||
sm = PortfolioStateMachineFactory.create(portfolio=portfolio)
|
||||
mock = Mock()
|
||||
monkeypatch.setattr("atst.jobs.provision_portfolio", mock)
|
||||
|
@@ -5,9 +5,12 @@ from unittest.mock import Mock
|
||||
from OpenSSL import crypto
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
from flask import template_rendered
|
||||
import pendulum
|
||||
|
||||
from atst.utils.notification_sender import NotificationSender
|
||||
|
||||
import tests.factories as factories
|
||||
|
||||
|
||||
@contextmanager
|
||||
def captured_templates(app):
|
||||
@@ -62,3 +65,46 @@ def make_crl_list(x509_obj, x509_path):
|
||||
issuer = x509_obj.issuer.public_bytes(default_backend())
|
||||
filename = os.path.basename(x509_path)
|
||||
return [(filename, issuer.hex())]
|
||||
|
||||
|
||||
class EnvQueryTest:
|
||||
@property
|
||||
def NOW(self):
|
||||
return pendulum.now()
|
||||
|
||||
@property
|
||||
def YESTERDAY(self):
|
||||
return self.NOW.subtract(days=1)
|
||||
|
||||
@property
|
||||
def TOMORROW(self):
|
||||
return self.NOW.add(days=1)
|
||||
|
||||
def create_portfolio_with_clins(
|
||||
self,
|
||||
start_and_end_dates,
|
||||
env_data=None,
|
||||
app_data=None,
|
||||
state_machine_status=None,
|
||||
):
|
||||
env_data = env_data or {}
|
||||
app_data = app_data or {}
|
||||
return factories.PortfolioFactory.create(
|
||||
state=state_machine_status,
|
||||
applications=[
|
||||
{
|
||||
"name": "Mos Eisley",
|
||||
"description": "Where Han shot first",
|
||||
"environments": [{"name": "thebar", **env_data}],
|
||||
**app_data,
|
||||
}
|
||||
],
|
||||
task_orders=[
|
||||
{
|
||||
"create_clins": [
|
||||
{"start_date": start_date, "end_date": end_date}
|
||||
for (start_date, end_date) in start_and_end_dates
|
||||
]
|
||||
}
|
||||
],
|
||||
)
|
||||
|
Reference in New Issue
Block a user