From f5e4b603cb9b8b286f954fea667760f7c174a04e Mon Sep 17 00:00:00 2001 From: tomdds Date: Wed, 22 Jan 2020 09:46:03 -0500 Subject: [PATCH] Bring naming conventions for methods and classes related to CSP provisioning in line with state machine --- atst/domain/csp/cloud.py | 171 ++++++++----------- atst/models/mixins/state_machines.py | 6 +- atst/models/portfolio_state_machine.py | 2 + tests/domain/cloud/test_azure_csp.py | 61 +++---- tests/domain/test_portfolio_state_machine.py | 14 +- tests/mock_azure.py | 1 + 6 files changed, 120 insertions(+), 135 deletions(-) diff --git a/atst/domain/csp/cloud.py b/atst/domain/csp/cloud.py index cd958781..afee36d9 100644 --- a/atst/domain/csp/cloud.py +++ b/atst/domain/csp/cloud.py @@ -186,8 +186,8 @@ class TenantCSPResult(AliasModel): tenant_id: str user_object_id: str - tenant_admin_username: str - tenant_admin_password: str + tenant_admin_username: Optional[str] + tenant_admin_password: Optional[str] class Config: fields = { @@ -232,7 +232,7 @@ class BillingProfileCLINBudget(AliasModel): """ -class BillingProfileCSPPayload(BaseCSPPayload): +class BillingProfileCreationCSPPayload(BaseCSPPayload): tenant_id: str billing_profile_display_name: str billing_account_name: str @@ -253,19 +253,19 @@ class BillingProfileCSPPayload(BaseCSPPayload): fields = {"billing_profile_display_name": "displayName"} -class BillingProfileCreateCSPResult(AliasModel): - billing_profile_validate_url: str - retry_after: int +class BillingProfileCreationCSPResult(AliasModel): + billing_profile_verify_url: str + billing_profile_retry_after: int class Config: fields = { - "billing_profile_validate_url": "Location", - "retry_after": "Retry-After", + "billing_profile_verify_url": "Location", + "billing_profile_retry_after": "Retry-After", } -class BillingProfileVerifyCSPPayload(BaseCSPPayload): - billing_profile_validate_url: str +class BillingProfileVerificationCSPPayload(BaseCSPPayload): + billing_profile_verify_url: str class BillingInvoiceSection(AliasModel): @@ -285,7 +285,7 @@ class BillingProfileProperties(AliasModel): fields = {"billing_profile_display_name": "displayName"} -class BillingProfileCSPResult(AliasModel): +class BillingProfileVerificationCSPResult(AliasModel): billing_profile_id: str billing_profile_name: str billing_profile_properties: BillingProfileProperties @@ -316,31 +316,31 @@ class BillingProfileTenantAccessCSPResult(AliasModel): } -class TaskOrderBillingCSPPayload(BaseCSPPayload): +class TaskOrderBillingCreationCSPPayload(BaseCSPPayload): billing_account_name: str billing_profile_name: str -class EnableTaskOrderBillingCSPResult(AliasModel): - task_order_billing_validate_url: str +class TaskOrderBillingCreationCSPResult(AliasModel): + task_order_billing_verify_url: str retry_after: int class Config: fields = { - "task_order_billing_validation_url": "Location", + "task_order_billing_verify_url": "Location", "retry_after": "Retry-After", } -class VerifyTaskOrderBillingCSPPayload(BaseCSPPayload): - task_order_billing_validate_url: str +class TaskOrderBillingVerificationCSPPayload(BaseCSPPayload): + task_order_billing_verify_url: str class BillingProfileEnabledPlanDetails(AliasModel): enabled_azure_plans: List[Dict] -class TaskOrderBillingCSPResult(AliasModel): +class TaskOrderBillingVerificationCSPResult(AliasModel): billing_profile_id: str billing_profile_name: str billing_profile_enabled_plan_details: BillingProfileEnabledPlanDetails @@ -353,7 +353,7 @@ class TaskOrderBillingCSPResult(AliasModel): } -class ReportCLINCSPPayload(BaseCSPPayload): +class BillingInstructionCSPPayload(BaseCSPPayload): amount: float start_date: str end_date: str @@ -363,7 +363,7 @@ class ReportCLINCSPPayload(BaseCSPPayload): billing_profile_name: str -class ReportCLINCSPResult(AliasModel): +class BillingInstructionCSPResult(AliasModel): reported_clin_name: str class Config: @@ -373,12 +373,10 @@ class ReportCLINCSPResult(AliasModel): class CloudProviderInterface: - - - def set_secret(secret_key: str, secret_value: str): + def set_secret(self, secret_key: str, secret_value: str): raise NotImplementedError() - def get_secret(secret_key: str, secret_value: str): + def get_secret(self, secret_key: str, secret_value: str): raise NotImplementedError() def root_creds(self) -> Dict: @@ -563,7 +561,7 @@ class MockCloudProvider(CloudProviderInterface): return {"id": self._id(), "credentials": self._auth_credentials} - def create_tenant(self, payload): + def create_tenant(self, payload: TenantCSPPayload): """ payload is an instance of TenantCSPPayload data class """ @@ -575,68 +573,41 @@ class MockCloudProvider(CloudProviderInterface): self._maybe_raise(self.NETWORK_FAILURE_PCT, self.NETWORK_EXCEPTION) self._maybe_raise(self.SERVER_FAILURE_PCT, self.SERVER_EXCEPTION) self._maybe_raise(self.UNAUTHORIZED_RATE, self.AUTHORIZATION_EXCEPTION) - # return tenant id, tenant owner id and tenant owner object id from: - response = {"tenantId": "string", "userId": "string", "objectId": "string"} - return { - "tenant_id": response["tenantId"], - "user_id": response["userId"], - "user_object_id": response["objectId"], - "tenant_admin_username": "test", - "tenant_admin_password": "test", - } - def create_billing_profile(self, payload): - # call billing profile creation endpoint, specifying owner - # Payload: - """ - { - "displayName": "string", - "poNumber": "string", - "address": { - "firstName": "string", - "lastName": "string", - "companyName": "string", - "addressLine1": "string", - "addressLine2": "string", - "addressLine3": "string", - "city": "string", - "region": "string", - "country": "string", - "postalCode": "string" - }, - "invoiceEmailOptIn": true, - Note: These last 2 are also the body for adding/updating new TOs/clins - "enabledAzurePlans": [ - { - "skuId": "string" - } - ], - "clinBudget": { - "amount": 0, - "startDate": "2019-12-18T16:47:40.909Z", - "endDate": "2019-12-18T16:47:40.909Z", - "externalReferenceId": "string" - } - } - """ + return TenantCSPResult(**{ + "tenant_id": "", + "user_id": "", + "user_object_id": "", + "tenant_admin_username": "test", + "tenant_admin_password": "test" + }).dict() + + def create_billing_profile_creation(self, payload: BillingProfileCreationCSPPayload): # response will be mostly the same as the body, but we only really care about the id self._maybe_raise(self.NETWORK_FAILURE_PCT, self.NETWORK_EXCEPTION) self._maybe_raise(self.SERVER_FAILURE_PCT, self.SERVER_EXCEPTION) self._maybe_raise(self.UNAUTHORIZED_RATE, self.AUTHORIZATION_EXCEPTION) - response = {"id": "string"} - # return {"billing_profile_id": response["id"]} - return { - "id": "/providers/Microsoft.Billing/billingAccounts/7c89b735-b22b-55c0-ab5a-c624843e8bf6:de4416ce-acc6-44b1-8122-c87c4e903c91_2019-05-31/billingProfiles/KQWI-W2SU-BG7-TGB", - "name": "KQWI-W2SU-BG7-TGB", - "properties": { - "address": { - "addressLine1": "123 S Broad Street, Suite 2400", - "city": "Philadelphia", - "companyName": "Promptworks", - "country": "US", - "postalCode": "19109", - "region": "PA", + return BillingProfileCreationCSPResult(**dict( + billing_profile_verify_url = "https://zombo.com", + billing_profile_retry_after = 10 + )).dict() + + def create_billing_profile_verification(self, payload: BillingProfileVerificationCSPPayload): + self._maybe_raise(self.NETWORK_FAILURE_PCT, self.NETWORK_EXCEPTION) + self._maybe_raise(self.SERVER_FAILURE_PCT, self.SERVER_EXCEPTION) + self._maybe_raise(self.UNAUTHORIZED_RATE, self.AUTHORIZATION_EXCEPTION) + return BillingProfileVerificationCSPResult(**{ + 'id': '/providers/Microsoft.Billing/billingAccounts/7c89b735-b22b-55c0-ab5a-c624843e8bf6:de4416ce-acc6-44b1-8122-c87c4e903c91_2019-05-31/billingProfiles/KQWI-W2SU-BG7-TGB', + 'name': 'KQWI-W2SU-BG7-TGB', + 'properties': { + 'address': { + 'addressLine1': '123 S Broad Street, Suite 2400', + 'city': 'Philadelphia', + 'companyName': 'Promptworks', + 'country': 'US', + 'postalCode': '19109', + 'region': 'PA' }, "currency": "USD", "displayName": "Test Billing Profile", @@ -653,8 +624,8 @@ class MockCloudProvider(CloudProviderInterface): } ], }, - "type": "Microsoft.Billing/billingAccounts/billingProfiles", - } + 'type': 'Microsoft.Billing/billingAccounts/billingProfiles' + }).dict() def create_billing_profile_tenant_access(self, payload): self._maybe_raise(self.NETWORK_FAILURE_PCT, self.NETWORK_EXCEPTION) @@ -795,7 +766,7 @@ class AzureCloudProvider(CloudProviderInterface): ) return secret_client.set_secret(secret_key, secret_value) - def get_secret(secret_key) + def get_secret(secret_key): credential = self._get_client_secret_credential_obj() secret_client = self.secrets.SecretClient( vault_url=self.vault_url, @@ -902,7 +873,7 @@ class AzureCloudProvider(CloudProviderInterface): else: return self._error(result.json()) - def create_billing_profile(self, payload: BillingProfileCSPPayload): + def create_billing_profile_creation(self, payload: BillingProfileCreationCSPPayload): sp_token = self._get_sp_token(payload.creds) if sp_token is None: raise AuthenticationException( @@ -925,14 +896,14 @@ class AzureCloudProvider(CloudProviderInterface): if result.status_code == 202: # 202 has location/retry after headers - return self._ok(BillingProfileCreateCSPResult(**result.headers)) + return self._ok(BillingProfileCreationCSPResult(**result.headers)) elif result.status_code == 200: # NB: Swagger docs imply call can sometimes resolve immediately - return self._ok(BillingProfileCSPResult(**result.json())) + return self._ok(BillingProfileVerificationCSPResult(**result.json())) else: return self._error(result.json()) - def validate_billing_profile_created(self, payload: BillingProfileVerifyCSPPayload): + def create_billing_profile_verification(self, payload: BillingProfileVerificationCSPPayload): sp_token = self._get_sp_token(payload.creds) if sp_token is None: raise AuthenticationException( @@ -944,14 +915,14 @@ class AzureCloudProvider(CloudProviderInterface): } result = self.sdk.requests.get( - payload.billing_profile_validate_url, headers=auth_header + payload.billing_profile_verify_url, headers=auth_header ) if result.status_code == 202: # 202 has location/retry after headers - return self._ok(BillingProfileCreateCSPResult(**result.headers)) + return self._ok(BillingProfileCreationCSPResult(**result.headers)) elif result.status_code == 200: - return self._ok(BillingProfileCSPResult(**result.json())) + return self._ok(BillingProfileVerificationCSPResult(**result.json())) else: return self._error(result.json()) @@ -979,7 +950,7 @@ class AzureCloudProvider(CloudProviderInterface): else: return self._error(result.json()) - def enable_task_order_billing(self, payload: TaskOrderBillingCSPPayload): + def create_task_order_billing_creation(self, payload: TaskOrderBillingCreationCSPPayload): sp_token = self._get_sp_token(payload.creds) request_body = [ { @@ -1001,13 +972,13 @@ class AzureCloudProvider(CloudProviderInterface): if result.status_code == 202: # 202 has location/retry after headers - return self._ok(BillingProfileCreateCSPResult(**result.headers)) + return self._ok(TaskOrderBillingCreationCSPResult(**result.headers)) elif result.status_code == 200: - return self._ok(TaskOrderBillingCSPResult(**result.json())) + return self._ok(TaskOrderBillingVerificationCSPResult(**result.json())) else: return self._error(result.json()) - def validate_task_order_billing_enabled(self, payload: TaskOrderBillingCSPPayload): + def create_task_order_billing_verification(self, payload: TaskOrderBillingVerificationCSPPayload): sp_token = self._get_sp_token(payload.creds) if sp_token is None: raise AuthenticationException( @@ -1018,17 +989,17 @@ class AzureCloudProvider(CloudProviderInterface): "Authorization": f"Bearer {sp_token}", } - result = self.sdk.requests.get(payload.task_order_billing_validate_url, headers=auth_header) + result = self.sdk.requests.get(payload.task_order_billing_verify_url, headers=auth_header) if result.status_code == 202: # 202 has location/retry after headers - return self._ok(TaskOrderBillingCSPResult(**result.headers)) + return self._ok(TaskOrderBillingCreationCSPResult(**result.headers)) elif result.status_code == 200: - return self._ok(TaskOrderBillingCSPResult(**result.json())) + return self._ok(TaskOrderBillingVerificationCSPResult(**result.json())) else: return self._error(result.json()) - def create_billing_instruction(self, payload: ReportCLINCSPPayload): + def create_billing_instruction(self, payload: BillingInstructionCSPPayload): sp_token = self._get_sp_token(payload.creds) if sp_token is None: raise AuthenticationException( @@ -1052,7 +1023,7 @@ class AzureCloudProvider(CloudProviderInterface): result = self.sdk.requests.put(url, headers=auth_header, json=request_body) if result.status_code == 200: - return self._ok(ReportCLINCSPResult(**result.json())) + return self._ok(BillingInstructionCSPResult(**result.json())) else: return self._error(result.json()) diff --git a/atst/models/mixins/state_machines.py b/atst/models/mixins/state_machines.py index 6938c8a9..8d50eb15 100644 --- a/atst/models/mixins/state_machines.py +++ b/atst/models/mixins/state_machines.py @@ -9,9 +9,11 @@ class StageStates(Enum): class AzureStages(Enum): TENANT = "tenant" - BILLING_PROFILE = "billing profile" + BILLING_PROFILE_CREATION = "billing profile creation" + BILLING_PROFILE_VERIFICATION = "billing profile verification" BILLING_PROFILE_TENANT_ACCESS = "billing profile tenant access" - TASK_ORDER_BILLING = "task order billing" + TASK_ORDER_BILLING_CREATION = "task order billing creation" + TASK_ORDER_BILLING_VERIFICATION = "task order billing verification" BILLING_INSTRUCTION = "billing instruction" diff --git a/atst/models/portfolio_state_machine.py b/atst/models/portfolio_state_machine.py index b8f29f24..89dc073b 100644 --- a/atst/models/portfolio_state_machine.py +++ b/atst/models/portfolio_state_machine.py @@ -199,6 +199,8 @@ class PortfolioStateMachine( # self.store_creds(self.portfolio, new_creds) except PydanticValidationError as exc: + print("is_csp_data_valid: False") + print(cls) print(exc.json()) return False diff --git a/tests/domain/cloud/test_azure_csp.py b/tests/domain/cloud/test_azure_csp.py index 577582d2..b2099903 100644 --- a/tests/domain/cloud/test_azure_csp.py +++ b/tests/domain/cloud/test_azure_csp.py @@ -5,18 +5,20 @@ from uuid import uuid4 from atst.domain.csp.cloud import ( AzureCloudProvider, - BillingProfileCreateCSPResult, - BillingProfileCSPPayload, - BillingProfileCSPResult, + BillingProfileCreationCSPResult, + BillingProfileCreationCSPPayload, BillingProfileTenantAccessCSPPayload, BillingProfileTenantAccessCSPResult, - BillingProfileVerifyCSPPayload, - ReportCLINCSPPayload, - ReportCLINCSPResult, - TaskOrderBillingCSPPayload, + BillingProfileVerificationCSPPayload, + BillingProfileVerificationCSPResult, + BillingInstructionCSPPayload, + BillingInstructionCSPResult, + TaskOrderBillingCreationCSPPayload, + TaskOrderBillingCreationCSPResult, + TaskOrderBillingVerificationCSPPayload, + TaskOrderBillingVerificationCSPResult, TenantCSPPayload, TenantCSPResult, - VerifyTaskOrderBillingCSPPayload, ) from tests.mock_azure import mock_azure, AUTH_CREDENTIALS @@ -167,7 +169,7 @@ def test_create_tenant(mock_azure: AzureCloudProvider): assert body.tenant_id == "60ff9d34-82bf-4f21-b565-308ef0533435" -def test_create_billing_profile(mock_azure: AzureCloudProvider): +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" } @@ -179,7 +181,7 @@ def test_create_billing_profile(mock_azure: AzureCloudProvider): } mock_result.status_code = 202 mock_azure.sdk.requests.post.return_value = mock_result - payload = BillingProfileCSPPayload( + payload = BillingProfileCreationCSPPayload( **dict( address=dict( address_line_1="123 S Broad Street, Suite 2400", @@ -195,9 +197,9 @@ def test_create_billing_profile(mock_azure: AzureCloudProvider): billing_account_name=BILLING_ACCOUNT_NAME, ) ) - result = mock_azure.create_billing_profile(payload) - body: BillingProfileCreateCSPResult = result.get("body") - assert body.retry_after == 10 + result = mock_azure.create_billing_profile_creation(payload) + body: BillingProfileCreationCSPResult = result.get("body") + assert body.billing_profile_retry_after == 10 def test_validate_billing_profile_creation(mock_azure: AzureCloudProvider): @@ -238,19 +240,19 @@ def test_validate_billing_profile_creation(mock_azure: AzureCloudProvider): } mock_azure.sdk.requests.get.return_value = mock_result - payload = BillingProfileVerifyCSPPayload( + payload = BillingProfileVerificationCSPPayload( **dict( creds={ "username": "username", "password": "password", "tenant_id": "tenant_id", }, - billing_profile_validate_url="https://management.azure.com/providers/Microsoft.Billing/billingAccounts/7c89b735-b22b-55c0-ab5a-c624843e8bf6:de4416ce-acc6-44b1-8122-c87c4e903c91_2019-05-31/operationResults/createBillingProfile_478d5706-71f9-4a8b-8d4e-2cbaca27a668?api-version=2019-10-01-preview", + billing_profile_verify_url="https://management.azure.com/providers/Microsoft.Billing/billingAccounts/7c89b735-b22b-55c0-ab5a-c624843e8bf6:de4416ce-acc6-44b1-8122-c87c4e903c91_2019-05-31/operationResults/createBillingProfile_478d5706-71f9-4a8b-8d4e-2cbaca27a668?api-version=2019-10-01-preview", ) ) - result = mock_azure.validate_billing_profile_created(payload) - body: BillingProfileCSPResult = result.get("body") + result = mock_azure.create_billing_profile_verification(payload) + body: BillingProfileVerificationCSPResult = result.get("body") assert body.billing_profile_name == "KQWI-W2SU-BG7-TGB" assert ( body.billing_profile_properties.billing_profile_display_name @@ -303,7 +305,7 @@ def test_create_billing_profile_tenant_access(mock_azure: AzureCloudProvider): ) -def test_create_task_order_billing(mock_azure: AzureCloudProvider): +def test_create_task_order_billing_creation(mock_azure: AzureCloudProvider): mock_azure.sdk.adal.AuthenticationContext.return_value.context.acquire_token_with_client_credentials.return_value = { "accessToken": "TOKEN" } @@ -317,7 +319,7 @@ def test_create_task_order_billing(mock_azure: AzureCloudProvider): mock_azure.sdk.requests.patch.return_value = mock_result - payload = TaskOrderBillingCSPPayload( + payload = TaskOrderBillingCreationCSPPayload( **dict( creds={ "username": "username", @@ -329,15 +331,15 @@ def test_create_task_order_billing(mock_azure: AzureCloudProvider): ) ) - result = mock_azure.enable_task_order_billing(payload) - body: BillingProfileCreateCSPResult = result.get("body") + result = mock_azure.create_task_order_billing_creation(payload) + body: TaskOrderBillingCreationCSPResult = result.get("body") assert ( - body.billing_profile_validate_url + body.task_order_billing_verify_url == "https://management.azure.com/providers/Microsoft.Billing/billingAccounts/7c89b735-b22b-55c0-ab5a-c624843e8bf6:de4416ce-acc6-44b1-8122-c87c4e903c91_2019-05-31/operationResults/patchBillingProfile_KQWI-W2SU-BG7-TGB:02715576-4118-466c-bca7-b1cd3169ff46?api-version=2019-10-01-preview" ) -def test_validate_task_order_billing_enabled(mock_azure): +def test_create_task_order_billing_verification(mock_azure): mock_azure.sdk.adal.AuthenticationContext.return_value.context.acquire_token_with_client_credentials.return_value = { "accessToken": "TOKEN" } @@ -381,19 +383,19 @@ def test_validate_task_order_billing_enabled(mock_azure): } mock_azure.sdk.requests.get.return_value = mock_result - payload = VerifyTaskOrderBillingCSPPayload( + payload = TaskOrderBillingVerificationCSPPayload( **dict( creds={ "username": "username", "password": "password", "tenant_id": "tenant_id", }, - task_order_billing_validate_url="https://management.azure.com/providers/Microsoft.Billing/billingAccounts/7c89b735-b22b-55c0-ab5a-c624843e8bf6:de4416ce-acc6-44b1-8122-c87c4e903c91_2019-05-31/operationResults/createBillingProfile_478d5706-71f9-4a8b-8d4e-2cbaca27a668?api-version=2019-10-01-preview", + task_order_billing_verify_url="https://management.azure.com/providers/Microsoft.Billing/billingAccounts/7c89b735-b22b-55c0-ab5a-c624843e8bf6:de4416ce-acc6-44b1-8122-c87c4e903c91_2019-05-31/operationResults/createBillingProfile_478d5706-71f9-4a8b-8d4e-2cbaca27a668?api-version=2019-10-01-preview", ) ) - result = mock_azure.validate_task_order_billing_enabled(payload) - body: BillingProfileEnabledCSPResult = result.get("body") + result = mock_azure.create_task_order_billing_verification(payload) + body: TaskOrderBillingVerificationCSPResult = result.get("body") assert body.billing_profile_name == "KQWI-W2SU-BG7-TGB" assert ( body.billing_profile_enabled_plan_details.enabled_azure_plans[0].get("skuId") @@ -420,7 +422,7 @@ def test_create_billing_instruction(mock_azure: AzureCloudProvider): mock_azure.sdk.requests.put.return_value = mock_result - payload = ReportCLINCSPPayload( + payload = BillingInstructionCSPPayload( **dict( creds={}, amount=1000.00, @@ -433,6 +435,5 @@ def test_create_billing_instruction(mock_azure: AzureCloudProvider): ) ) result = mock_azure.create_billing_instruction(payload) - body: ReportCLINCSPResult = result.get("body") + body: BillingInstructionCSPResult = result.get("body") assert body.reported_clin_name == "TO1:CLIN001" - diff --git a/tests/domain/test_portfolio_state_machine.py b/tests/domain/test_portfolio_state_machine.py index 9bd2c842..dcbc4bfd 100644 --- a/tests/domain/test_portfolio_state_machine.py +++ b/tests/domain/test_portfolio_state_machine.py @@ -119,17 +119,25 @@ def test_fsm_transition_start(portfolio): "billing_profile_display_name": "My Billing Profile", } - collected_data = dict(list(csp_data.items()) + list(portfolio_data.items())) + config = {"billing_account_name": "billing_account_name"} + + collected_data = dict( + list(csp_data.items()) + list(portfolio_data.items()) + list(config.items()) + ) sm.trigger_next_transition(creds=creds, csp_data=collected_data) assert sm.state == FSMStates.TENANT_CREATED assert portfolio.csp_data.get("tenant_id", None) is not None - + print(portfolio.csp_data.keys()) if portfolio.csp_data is not None: csp_data = portfolio.csp_data else: csp_data = {} - collected_data = dict(list(csp_data.items()) + list(portfolio_data.items())) + collected_data = dict( + list(csp_data.items()) + list(portfolio_data.items()) + list(config.items()) + ) sm.trigger_next_transition(creds=creds, csp_data=collected_data) assert sm.state == FSMStates.BILLING_PROFILE_CREATED + print(portfolio.csp_data.keys()) + diff --git a/tests/mock_azure.py b/tests/mock_azure.py index ecfafaac..23e9515c 100644 --- a/tests/mock_azure.py +++ b/tests/mock_azure.py @@ -8,6 +8,7 @@ AZURE_CONFIG = { "AZURE_SECRET_KEY": "MOCK", "AZURE_TENANT_ID": "MOCK", "AZURE_POLICY_LOCATION": "policies", + "AZURE_VAULT_URL": "http://vault", } AUTH_CREDENTIALS = {