Add functionality for creating and verifying subscriptions.
Currently the create call will be consumed by on-demand requests from the frontend, and the 2 stage create will be used by the enviroment management group provisioning to verify an initial subscription was created.
This commit is contained in:
@@ -12,7 +12,6 @@ from atst.domain.csp.cloud.models import (
|
||||
AdminRoleDefinitionCSPResult,
|
||||
ApplicationCSPPayload,
|
||||
ApplicationCSPResult,
|
||||
BaseCSPPayload,
|
||||
BillingInstructionCSPPayload,
|
||||
BillingInstructionCSPResult,
|
||||
BillingProfileCreationCSPPayload,
|
||||
@@ -21,6 +20,10 @@ from atst.domain.csp.cloud.models import (
|
||||
BillingProfileTenantAccessCSPResult,
|
||||
BillingProfileVerificationCSPPayload,
|
||||
BillingProfileVerificationCSPResult,
|
||||
SubscriptionCreationCSPPayload,
|
||||
SubscriptionCreationCSPResult,
|
||||
SubscriptionVerificationCSPPayload,
|
||||
SuscriptionVerificationCSPResult,
|
||||
TaskOrderBillingCreationCSPPayload,
|
||||
TaskOrderBillingCreationCSPResult,
|
||||
TaskOrderBillingVerificationCSPPayload,
|
||||
@@ -42,40 +45,6 @@ from atst.domain.csp.cloud.models import (
|
||||
BILLING_ACCOUNT_NAME = "52865e4c-52e8-5a6c-da6b-c58f0814f06f:7ea5de9d-b8ce-4901-b1c5-d864320c7b03_2019-05-31"
|
||||
|
||||
|
||||
def test_create_subscription_succeeds(mock_azure: AzureCloudProvider):
|
||||
environment = EnvironmentFactory.create()
|
||||
|
||||
subscription_id = str(uuid4())
|
||||
|
||||
credentials = mock_azure._get_credential_obj(AUTH_CREDENTIALS)
|
||||
display_name = "Test Subscription"
|
||||
billing_profile_id = str(uuid4())
|
||||
sku_id = str(uuid4())
|
||||
management_group_id = (
|
||||
environment.cloud_id # environment.csp_details.management_group_id?
|
||||
)
|
||||
billing_account_name = (
|
||||
"?" # environment.application.portfilio.csp_details.billing_account.name?
|
||||
)
|
||||
invoice_section_name = "?" # environment.name? or something specific to billing?
|
||||
|
||||
mock_azure.sdk.subscription.SubscriptionClient.return_value.subscription_factory.create_subscription.return_value.result.return_value.subscription_link = (
|
||||
f"subscriptions/{subscription_id}"
|
||||
)
|
||||
|
||||
result = mock_azure._create_subscription(
|
||||
credentials,
|
||||
display_name,
|
||||
billing_profile_id,
|
||||
sku_id,
|
||||
management_group_id,
|
||||
billing_account_name,
|
||||
invoice_section_name,
|
||||
)
|
||||
|
||||
assert result == subscription_id
|
||||
|
||||
|
||||
def mock_management_group_create(mock_azure, spec_dict):
|
||||
mock_azure.sdk.managementgroups.ManagementGroupsAPI.return_value.management_groups.create_or_update.return_value.result.return_value = (
|
||||
spec_dict
|
||||
@@ -119,7 +88,7 @@ def test_create_application_succeeds(mock_azure: AzureCloudProvider):
|
||||
tenant_id="1234", display_name=application.name, parent_id=str(uuid4())
|
||||
)
|
||||
|
||||
result = mock_azure.create_application(payload)
|
||||
result: ApplicationCSPResult = mock_azure.create_application(payload)
|
||||
|
||||
assert result.id == "Test Id"
|
||||
|
||||
@@ -609,3 +578,65 @@ def test_create_tenant_principal_ownership(mock_azure: AzureCloudProvider):
|
||||
)
|
||||
|
||||
assert result.principal_owner_assignment_id == "id"
|
||||
|
||||
|
||||
def test_create_subscription_creation(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 = "my fake token"
|
||||
|
||||
mock_result = Mock()
|
||||
mock_result.status_code = 202
|
||||
mock_result.headers = {
|
||||
"Location": "https://verify.me",
|
||||
"Retry-After": "10",
|
||||
}
|
||||
mock_result.json.return_value = {}
|
||||
mock_azure.sdk.requests.put.return_value = mock_result
|
||||
management_group_id = str(uuid4())
|
||||
payload = SubscriptionCreationCSPPayload(
|
||||
**dict(
|
||||
tenant_id="60ff9d34-82bf-4f21-b565-308ef0533435",
|
||||
parent_group_id=management_group_id,
|
||||
billing_account_name="7c89b735-b22b-55c0-ab5a-c624843e8bf6:de4416ce-acc6-44b1-8122-c87c4e903c91_2019-05-31",
|
||||
billing_profile_name="KQWI-W2SU-BG7-TGB",
|
||||
invoice_section_name="6HMZ-2HLO-PJA-TGB",
|
||||
)
|
||||
)
|
||||
|
||||
result: SubscriptionCreationCSPResult = mock_azure.create_subscription_creation(
|
||||
payload
|
||||
)
|
||||
|
||||
assert result.subscription_verify_url == "https://verify.me"
|
||||
|
||||
|
||||
def test_create_subscription_verification(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 = "my fake token"
|
||||
|
||||
mock_result = Mock()
|
||||
mock_result.ok = True
|
||||
mock_result.json.return_value = {
|
||||
"subscriptionLink": "/subscriptions/60fbbb72-0516-4253-ab18-c92432ba3230"
|
||||
}
|
||||
mock_azure.sdk.requests.get.return_value = mock_result
|
||||
|
||||
payload = SubscriptionVerificationCSPPayload(
|
||||
**dict(
|
||||
tenant_id="60ff9d34-82bf-4f21-b565-308ef0533435",
|
||||
subscription_verify_url="https://verify.me",
|
||||
)
|
||||
)
|
||||
|
||||
result: SuscriptionVerificationCSPResult = mock_azure.create_subscription_verification(
|
||||
payload
|
||||
)
|
||||
assert result.subscription_id == "60fbbb72-0516-4253-ab18-c92432ba3230"
|
||||
|
@@ -1,35 +1,38 @@
|
||||
import uuid
|
||||
from flask import url_for, get_flashed_messages
|
||||
from unittest.mock import Mock
|
||||
import datetime
|
||||
from werkzeug.datastructures import ImmutableMultiDict
|
||||
import uuid
|
||||
from unittest.mock import Mock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
from flask import get_flashed_messages, url_for
|
||||
from tests.factories import *
|
||||
from tests.mock_azure import mock_azure
|
||||
from tests.utils import captured_templates
|
||||
from werkzeug.datastructures import ImmutableMultiDict
|
||||
|
||||
from atst.domain.applications import Applications
|
||||
from atst.database import db
|
||||
from atst.domain.application_roles import ApplicationRoles
|
||||
from atst.domain.applications import Applications
|
||||
from atst.domain.common import Paginator
|
||||
from atst.domain.csp.cloud.azure_cloud_provider import AzureCloudProvider
|
||||
from atst.domain.csp.cloud.exceptions import GeneralCSPException
|
||||
from atst.domain.csp.cloud.models import SubscriptionCreationCSPResult
|
||||
from atst.domain.environment_roles import EnvironmentRoles
|
||||
from atst.domain.invitations import ApplicationInvitations
|
||||
from atst.domain.common import Paginator
|
||||
from atst.domain.csp.cloud.exceptions import GeneralCSPException
|
||||
from atst.domain.permission_sets import PermissionSets
|
||||
from atst.models.application_role import Status as ApplicationRoleStatus
|
||||
from atst.models.environment_role import CSPRole, EnvironmentRole
|
||||
from atst.models.permissions import Permissions
|
||||
from atst.forms.application import EditEnvironmentForm
|
||||
from atst.forms.application_member import UpdateMemberForm
|
||||
from atst.forms.data import ENV_ROLE_NO_ACCESS as NO_ACCESS
|
||||
from atst.models.application_role import Status as ApplicationRoleStatus
|
||||
from atst.models.environment_role import CSPRole, EnvironmentRole
|
||||
from atst.models.permissions import Permissions
|
||||
from atst.routes.applications.settings import (
|
||||
filter_env_roles_form_data,
|
||||
filter_env_roles_data,
|
||||
filter_env_roles_form_data,
|
||||
get_environments_obj_for_app,
|
||||
handle_create_member,
|
||||
handle_update_member,
|
||||
)
|
||||
|
||||
from tests.utils import captured_templates
|
||||
|
||||
|
||||
def test_updating_application_environments_success(client, user_session):
|
||||
portfolio = PortfolioFactory.create()
|
||||
@@ -779,22 +782,41 @@ def test_handle_update_member_with_error(set_g, monkeypatch, mock_logger):
|
||||
assert mock_logger.messages[-1] == exception
|
||||
|
||||
|
||||
def test_create_subscription_success(client, user_session):
|
||||
def test_create_subscription_success(
|
||||
client, user_session, mock_azure: AzureCloudProvider
|
||||
):
|
||||
environment = EnvironmentFactory.create()
|
||||
|
||||
user_session(environment.portfolio.owner)
|
||||
response = client.post(
|
||||
url_for("applications.create_subscription", environment_id=environment.id),
|
||||
)
|
||||
environment.cloud_id = "management/group/id"
|
||||
environment.application.portfolio.csp_data = {
|
||||
"billing_account_name": "xxxx-xxxx-xxx-xxx",
|
||||
"billing_profile_name": "xxxxxxxxxxx:xxxxxxxxxxxxx_xxxxxx",
|
||||
"tenant_id": "xxxxxxxxxxx-xxxxxxxxxx-xxxxxxx-xxxxx",
|
||||
"billing_profile_properties": {
|
||||
"invoice_sections": [{"invoice_section_name": "xxxx-xxxx-xxx-xxx"}]
|
||||
},
|
||||
}
|
||||
|
||||
assert response.status_code == 302
|
||||
assert response.location == url_for(
|
||||
"applications.settings",
|
||||
application_id=environment.application.id,
|
||||
_external=True,
|
||||
fragment="application-environments",
|
||||
_anchor="application-environments",
|
||||
)
|
||||
with patch.object(
|
||||
AzureCloudProvider, "create_subscription", wraps=mock_azure.create_subscription,
|
||||
) as create_subscription:
|
||||
create_subscription.return_value = SubscriptionCreationCSPResult(
|
||||
subscription_verify_url="", subscription_retry_after=""
|
||||
)
|
||||
|
||||
response = client.post(
|
||||
url_for("applications.create_subscription", environment_id=environment.id),
|
||||
)
|
||||
|
||||
assert response.status_code == 302
|
||||
assert response.location == url_for(
|
||||
"applications.settings",
|
||||
application_id=environment.application.id,
|
||||
_external=True,
|
||||
fragment="application-environments",
|
||||
_anchor="application-environments",
|
||||
)
|
||||
|
||||
|
||||
def test_create_subscription_failure(client, user_session, monkeypatch):
|
||||
@@ -809,6 +831,16 @@ def test_create_subscription_failure(client, user_session, monkeypatch):
|
||||
)
|
||||
|
||||
user_session(environment.portfolio.owner)
|
||||
environment.cloud_id = "management/group/id"
|
||||
environment.application.portfolio.csp_data = {
|
||||
"billing_account_name": "xxxx-xxxx-xxx-xxx",
|
||||
"billing_profile_name": "xxxxxxxxxxx:xxxxxxxxxxxxx_xxxxxx",
|
||||
"tenant_id": "xxxxxxxxxxx-xxxxxxxxxx-xxxxxxx-xxxxx",
|
||||
"billing_profile_properties": {
|
||||
"invoice_sections": [{"invoice_section_name": "xxxx-xxxx-xxx-xxx"}]
|
||||
},
|
||||
}
|
||||
|
||||
response = client.post(
|
||||
url_for("applications.create_subscription", environment_id=environment.id),
|
||||
)
|
||||
|
Reference in New Issue
Block a user