feat(bridge): allow random provider selection

This commit is contained in:
Iain Learmonth 2023-02-26 15:06:40 +00:00
parent e17b564370
commit 24e464653b
3 changed files with 58 additions and 7 deletions

View file

@ -1,9 +1,10 @@
import datetime
import logging
import random
from typing import Tuple, List
from app import db
from app.models.bridges import BridgeConf, Bridge
from app.models.bridges import BridgeConf, Bridge, ProviderAllocation
from app.models.cloud import CloudProvider, CloudAccount
from app.terraform import BaseAutomation
@ -40,11 +41,11 @@ def create_bridges_in_account(bridgeconf: BridgeConf, account: CloudAccount, cou
return created
def create_bridges(bridgeconf: BridgeConf, count: int) -> int:
def create_bridges_by_cost(bridgeconf: BridgeConf, count: int) -> int:
"""
Creates a bridge resource for the given bridge configuration.
Creates bridge resources for the given bridge configuration using the cheapest available provider.
"""
logging.debug("Creating %s bridges for configuration %s", count, bridgeconf.id)
logging.debug("Creating %s bridges by cost for configuration %s", count, bridgeconf.id)
created = 0
for provider in BRIDGE_PROVIDERS:
if created >= count:
@ -54,13 +55,48 @@ def create_bridges(bridgeconf: BridgeConf, count: int) -> int:
CloudAccount.destroyed.is_(None),
CloudAccount.enabled.is_(True),
CloudAccount.provider == provider,
):
).all():
logging.info("Creating bridges in %s", account)
created += create_bridges_in_account(bridgeconf, account, count - created)
logging.debug("Created %s bridges", created)
return created
def _accounts_with_room() -> List[CloudAccount]:
accounts = CloudAccount.query.filter(
CloudAccount.destroyed.is_(None),
CloudAccount.enabled.is_(True),
).all()
accounts_with_room: List[CloudAccount] = []
for account in accounts:
if len(active_bridges_in_account(account)) < account.max_instances:
accounts_with_room.append(account)
return accounts_with_room
def create_bridges_by_random(bridgeconf: BridgeConf, count: int) -> int:
"""
Creates bridge resources for the given bridge configuration using random providers.
"""
logging.debug("Creating %s bridges by random for configuration %s", count, bridgeconf.id)
created = 0
while candidate_accounts := _accounts_with_room():
# Not security-critical random number generation
account = random.choice(candidate_accounts) # nosec: B311
create_bridges_in_account(bridgeconf, account, 1)
created += 1
if created == count:
return count
return created # No account with room
def create_bridges(bridgeconf: BridgeConf, count: int) -> int:
if bridgeconf.provider_allocation == ProviderAllocation.COST:
return create_bridges_by_cost(bridgeconf, count)
else:
return create_bridges_by_random(bridgeconf, count)
def deprecate_bridges(bridgeconf: BridgeConf, count: int, reason: str = "redundant") -> int:
logging.debug("Deprecating %s bridges (%s) for configuration %s", count, reason, bridgeconf.id)
deprecated = 0