Skip to content

Commit

Permalink
Merge pull request #71 from cloudblue/feature/LITE-28190-Deactivate-M…
Browse files Browse the repository at this point in the history
…arketplaces-when-we-receive-an-unlisted-event

LITE-28190: Deactivating markerplace from deployment.
  • Loading branch information
d3rky authored Aug 2, 2023
2 parents 8171256 + 932e104 commit 6065057
Show file tree
Hide file tree
Showing 10 changed files with 307 additions and 40 deletions.
26 changes: 17 additions & 9 deletions connect_ext_ppr/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,12 @@
from connect.eaas.core.responses import BackgroundResponse
from sqlalchemy.exc import DBAPIError

from connect_ext_ppr.service import add_deployments, process_ppr_from_product_update
from connect_ext_ppr.utils import get_all_info, get_marketplaces, get_products
from connect_ext_ppr.service import (
add_deployments,
deactivate_marketplaces,
process_ppr_from_product_update,
)
from connect_ext_ppr.utils import get_all_listing_info, get_marketplaces, get_products


@variables([
Expand Down Expand Up @@ -46,17 +50,18 @@ def handle_listing_processing(self, request):
product contained in the listing.
'''
self.logger.info(f"Received listing {request['id']} status={request['status']}")
mp = get_marketplaces(
self.installation_client,
[request['contract']['marketplace']['id']],
).first()

request['contract']['marketplace'] = mp
if request['status'] == 'listed':
mp = get_marketplaces(
self.installation_client,
[request['contract']['marketplace']['id']],
).first()
prod = get_products(self.installation_client, [request['product']['id']]).first()
request['contract']['marketplace'] = mp
request['product'] = prod
add_deployments(self.installation, [request], self.config, self.logger)
else:
self.logger.info(f"Skipping event for listing {request['id']}.")
deactivate_marketplaces(self.installation, [request], self.config, self.logger)
return BackgroundResponse.done()

@event(
Expand Down Expand Up @@ -102,8 +107,11 @@ def on_installation_status_change(self, request):
f"id={request['id']}, environment={request['environment']['id']}",
)
try:
listings = get_all_info(self.installation_client)
listings = get_all_listing_info(self.installation_client)
add_deployments(self.installation, listings, self.config, self.logger)

listings = get_all_listing_info(self.installation_client, status='unlisted')
deactivate_marketplaces(self.installation, listings, self.config, self.logger)
except (ClientError, DBAPIError):
return BackgroundResponse.reschedule()
else:
Expand Down
1 change: 1 addition & 0 deletions connect_ext_ppr/models/deployment.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,5 +97,6 @@ class MarketplaceConfiguration(Model):
deployment_id = db.Column(db.ForeignKey(Deployment.id), nullable=True)
deployment_request = db.Column(db.ForeignKey(DeploymentRequest.id), nullable=True)
ppr_id = db.Column(db.String, db.ForeignKey(PPRVersion.id))
active = db.Column(db.Boolean(), default=True)

ppr = relationship('PPRVersion', foreign_keys='MarketplaceConfiguration.ppr_id')
60 changes: 59 additions & 1 deletion connect_ext_ppr/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from datetime import datetime

import pandas as pd
from sqlalchemy import exists
from sqlalchemy import exists, update
from sqlalchemy.exc import DBAPIError
from sqlalchemy.sql import desc

Expand Down Expand Up @@ -352,3 +352,61 @@ def add_new_deployment_request(db, dr_data, deployment, account_id, logger):
logger.error(ex)
db.rollback()
raise ExtensionHttpError.EXT_003()


def deactivate_marketplaces(installation, listings, config, logger):
with get_db_ctx_manager(config) as db:
for li in listings:
marketplace_id = li['contract']['marketplace']['id']
product_id = li['product']['id']
hubs = [hub['hub']['id'] for hub in li['contract']['marketplace']['hubs']]
deployments = [d.id for d in db.query(Deployment.id).filter_by(
product_id=product_id,
account_id=installation['owner']['id'],
).filter(
Deployment.hub_id.in_(hubs),
).all()]

stmt = (
update(MarketplaceConfiguration)
.where(
MarketplaceConfiguration.marketplace == marketplace_id,
MarketplaceConfiguration.deployment_id.in_(deployments))
.values(active=False)
.returning(MarketplaceConfiguration.deployment_id)
)

result = db.execute(stmt)
logger.info(
f'Marketplace {marketplace_id} has been deactivate from deployments {result.all()}',
)

deployments_requests = (
db.query(DeploymentRequest.id)
.filter(
DeploymentRequest.deployment_id.in_(deployments),
DeploymentRequest.status.in_([
DeploymentRequest.STATUSES.pending,
DeploymentRequest.STATUSES.processing,
]),
)
)

stmt = (
update(MarketplaceConfiguration)
.where(
MarketplaceConfiguration.marketplace == marketplace_id,
MarketplaceConfiguration.deployment_request.in_(
[dr.id for dr in deployments_requests],
))
.values(active=False)
.returning(MarketplaceConfiguration.deployment_request)
)

result = db.execute(stmt)
logger.info(
f'Marketplace {marketplace_id} has been deactivate from deployments requests '
f'{result.all()}',
)

db.commit()
8 changes: 4 additions & 4 deletions connect_ext_ppr/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ def _get_installation(client):
return client('devops').installations.filter(rql).first()


def get_listings(client):
rql = R().status.eq("listed")
def get_listings(client, status='listed'):
rql = R().status.eq(status)
return client.listings.filter(rql)


Expand Down Expand Up @@ -158,8 +158,8 @@ def get_configuration_from_media(client, account_id, deployment_id, media_id):


@connect_error
def get_all_info(client):
listings = list(get_listings(client))
def get_all_listing_info(client, status='listed'):
listings = list(get_listings(client, status))
mkp_ids = list({li['contract']['marketplace']['id'] for li in listings})
prod_ids = list({li['product']['id'] for li in listings})
marketplaces = list(get_marketplaces(client, mkp_ids))
Expand Down
21 changes: 15 additions & 6 deletions connect_ext_ppr/webapp.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
add_deployments,
add_new_deployment_request,
create_ppr,
deactivate_marketplaces,
validate_configuration,
)
from connect_ext_ppr.schemas import (
Expand Down Expand Up @@ -79,7 +80,7 @@
_get_extension_client,
_get_installation,
filter_object_list_by_id,
get_all_info,
get_all_listing_info,
get_client_object,
get_configuration_schema,
get_deployment_by_id,
Expand Down Expand Up @@ -148,12 +149,17 @@ def add_dep_request(
ppr = db.query(PPRVersion).filter_by(id=deployment_request.ppr.id).first()
validate_ppr_version_belongs_to_deployment(ppr, deployment)

dep_marketplaces = db.query(MarketplaceConfiguration).filter_by(
active=True,
deployment_id=deployment.id,
)
dr_marketplaces = [m.id for m in deployment_request.marketplaces.choices]
validate_dr_marketplaces(
dr_marketplaces,
[m.marketplace for m in deployment.marketplaces],
[m.marketplace for m in dep_marketplaces],
)
validate_marketplaces_ppr(ppr, dr_marketplaces, deployment.marketplaces)

validate_marketplaces_ppr(ppr, dr_marketplaces, dep_marketplaces)

instance = add_new_deployment_request(
db, deployment_request, deployment, account_id, logger,
Expand Down Expand Up @@ -384,7 +390,7 @@ def get_deployments(
installation: dict = Depends(get_installation),
):
deployments = db.query(Deployment).filter_by(account_id=installation['owner']['id'])
listings = get_all_info(client)
listings = get_all_listing_info(client)
vendors = [li['vendor'] for li in listings]
hubs = [hub['hub'] for li in listings for hub in li['contract']['marketplace']['hubs']]
response_list = []
Expand Down Expand Up @@ -632,7 +638,7 @@ def get_marketplaces_by_deployment(

mkplc_configs = db.query(MarketplaceConfiguration).options(
selectinload(MarketplaceConfiguration.ppr),
).filter_by(deployment_id=deployment_id)
).filter_by(deployment_id=deployment_id, active=True)

mkplc_ids = [m.marketplace for m in mkplc_configs]

Expand Down Expand Up @@ -762,8 +768,11 @@ def on_startup(cls, logger, config):
client = _get_extension_client(logger)
installation = _get_installation(client)
if installation['owner']['id'] == installation['environment']['extension']['owner']['id']:
listings = get_all_info(client)
listings = get_all_listing_info(client)
# For extension owner we do not have available the installation
# event to handle populate Deployment table, so for this particular case
# we make use of `on_startup` webapplication event function.
add_deployments(installation, listings, config, logger)

listings = get_all_listing_info(client, status='unlisted')
deactivate_marketplaces(installation, listings, config, logger)
11 changes: 4 additions & 7 deletions tests/api/test_deployment_requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -531,6 +531,7 @@ def test_create_deployment_invalid_marketplace(
other_dep = deployment_factory(hub_id=hub_data['id'])

marketplace_config_factory(deployment=dep, marketplace_id='MP-124')
marketplace_config_factory(deployment=dep, marketplace_id='MP-127', active=False)
marketplace_config_factory(deployment=dep, marketplace_id='MP-123', ppr_id=ppr.id)
marketplace_config_factory(deployment=other_dep, marketplace_id='MP-126', ppr_id=ppr.id)

Expand All @@ -540,7 +541,7 @@ def test_create_deployment_invalid_marketplace(
'manually': True,
'delegate_l2': True,
'marketplaces': {
'choices': [{'id': 'MP-125'}, {'id': 'MP-123'}, {'id': 'MP-126'}],
'choices': [{'id': 'MP-125'}, {'id': 'MP-123'}, {'id': 'MP-126'}, {'id': 'MP-127'}],
'all': False,
},
}
Expand All @@ -553,7 +554,7 @@ def test_create_deployment_invalid_marketplace(
assert response.status_code == 400
assert response.json()['error_code'] == 'VAL_002', response.json()
assert response.json()['errors'] == [
'marketplaces: This values [\'MP-125\', \'MP-126\'] are invalid.',
'marketplaces: This values [\'MP-125\', \'MP-126\', \'MP-127\'] are invalid.',
]


Expand Down Expand Up @@ -740,7 +741,6 @@ def test_create_deployment_request_w_open_request(


def test_list_deployment_request_marketplaces(
dbsession,
mocker,
deployment_factory,
deployment_request_factory,
Expand All @@ -766,6 +766,7 @@ def test_list_deployment_request_marketplaces(

marketplace_config_factory(deployment_request=dr1, marketplace_id=m1['id'])
marketplace_config_factory(deployment_request=dr1, marketplace_id=m2['id'], ppr_id=ppr.id)
marketplace_config_factory(deployment_request=dr1, marketplace_id='MP-12345')

marketplace_config_factory(deployment=dep1, marketplace_id=m1['id'])
marketplace_config_factory(deployment=dep1, marketplace_id=m2['id'])
Expand Down Expand Up @@ -815,7 +816,6 @@ def test_list_deployment_request_marketplaces_not_found(


def test_abort_deployment_request_aborted(
dbsession,
mocker,
deployment_factory,
deployment_request_factory,
Expand Down Expand Up @@ -889,7 +889,6 @@ def test_abort_deployment_request_aborted(


def test_abort_deployment_request_aborting(
dbsession,
mocker,
deployment_factory,
deployment_request_factory,
Expand Down Expand Up @@ -970,8 +969,6 @@ def test_abort_deployment_request_aborting(


def test_abort_deployment_request_not_allow(
dbsession,
mocker,
deployment_factory,
deployment_request_factory,
installation,
Expand Down
5 changes: 3 additions & 2 deletions tests/api/test_deployments.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def test_get_deployments(
api_client,
):
mocker.patch(
'connect_ext_ppr.webapp.get_all_info',
'connect_ext_ppr.webapp.get_all_listing_info',
return_value=[
{
'product': {
Expand Down Expand Up @@ -82,7 +82,7 @@ def test_get_deployments_empty(
api_client,
):
mocker.patch(
'connect_ext_ppr.webapp.get_all_info',
'connect_ext_ppr.webapp.get_all_listing_info',
return_value=[],
)
response = api_client.get(
Expand Down Expand Up @@ -187,6 +187,7 @@ def test_get_deployments_marketplaces(
ppr = ppr_version_factory(deployment=deployment)
marketplace_config_factory(deployment=deployment, marketplace_id=m1['id'], ppr_id=ppr.id)
marketplace_config_factory(deployment=deployment, marketplace_id=m2['id'])
marketplace_config_factory(deployment=deployment, marketplace_id='MP-657', active=False)
marketplace_config_factory(deployment=another_dep, marketplace_id=m3['id'])

response = api_client.get(
Expand Down
10 changes: 8 additions & 2 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -268,11 +268,17 @@ def _build_file(

@pytest.fixture
def marketplace_config_factory(dbsession):
def _build_mc(marketplace_id, deployment=None, deployment_request=None, ppr_id=None):

def _build_mc(
marketplace_id,
deployment=None,
deployment_request=None,
ppr_id=None,
active=True,
):
mp = MarketplaceConfiguration(
marketplace=marketplace_id,
ppr_id=ppr_id,
active=active,
)
if deployment:
mp.deployment_id = deployment.id
Expand Down
Loading

0 comments on commit 6065057

Please sign in to comment.