Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LITE-28078: Adding marketplaces to deployment + Retrieve deployment's marketplaces #49

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions connect_ext_ppr/models/deployment.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,6 @@ class MarketplaceConfiguration(Model):
marketplace = db.Column(db.String(16))
deployment = 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))

ppr = relationship('PPRVersion', foreign_keys='MarketplaceConfiguration.ppr_id')
9 changes: 9 additions & 0 deletions connect_ext_ppr/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,3 +118,12 @@ class DeploymentRequestSchema(NonNullSchema):

class Config:
orm_mode = True


class MarketplaceSchema(NonNullSchema):
id: str
name: str
icon: str
external_id: Optional[str]

ppr: Optional[PPRVersionReferenceSchema]
41 changes: 36 additions & 5 deletions connect_ext_ppr/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from connect_ext_ppr.db import get_db_ctx_manager
from connect_ext_ppr.errors import ExtensionHttpError
from connect_ext_ppr.models.configuration import Configuration
from connect_ext_ppr.models.deployment import Deployment
from connect_ext_ppr.models.deployment import Deployment, MarketplaceConfiguration
from connect_ext_ppr.models.file import File
from connect_ext_ppr.models.ppr import PPRVersion
from connect_ext_ppr.models.replicas import Product
Expand Down Expand Up @@ -43,31 +43,50 @@ def insert_product_from_listing(db, listing_data, logger):
db.commit()


def add_marketplaces_to_deployment(db, deployment, marketplaces):
"""
Asociates all the marketplaces to deployment
:param db: dbsession
:param deployment: Deployment instance
:param marketplaces: list of marketplaces' ids
"""
configs = []
for marketplace in marketplaces:
mc = MarketplaceConfiguration(
deployment=deployment.id,
marketplace=marketplace,
)
configs.append(mc)
db.add_all(configs)


def add_deployments(installation, listings, config, logger):
with get_db_ctx_manager(config) as db:
deployments = []
deployments_marketplaces = {}
seen = set()
for li in listings:
insert_product_from_listing(db, li, logger)
product_id = li['product']['id']

for hub in li['contract']['marketplace']['hubs']:
comb = (product_id, installation['owner']['id'], hub['hub']['id'])
hub_id = hub['hub']['id']
comb = (product_id, installation['owner']['id'], hub_id)
q = db.query(Deployment).filter_by(
product_id=product_id,
account_id=installation['owner']['id'],
hub_id=hub['hub']['id'],
hub_id=hub_id,
)
if db.query(q.exists()).scalar():
dep = q.first()
logger.info(
f"Deployment {dep.id} for hub {hub['hub']['id']} already exists.",
f"Deployment {dep.id} for hub {hub_id} already exists.",
)
continue
if comb not in seen:
dep = Deployment(
product_id=product_id,
hub_id=hub['hub']['id'],
hub_id=hub_id,
vendor_id=li['vendor']['id'],
account_id=installation['owner']['id'],
)
Expand All @@ -77,8 +96,20 @@ def add_deployments(installation, listings, config, logger):
)
deployments.append(dep)
seen.add(comb)
key = f"{product_id}#{hub_id}"
deployments_marketplaces.setdefault(
key,
{'deployment': dep, 'marketplaces': []},
)
deployments_marketplaces[key]['marketplaces'].append(
li['contract']['marketplace']['id'],
)
db.set_verbose_all(deployments)
db.commit()

for data in deployments_marketplaces.values():
add_marketplaces_to_deployment(db, data['deployment'], data['marketplaces'])

if deployments:
db.expire_all()
dep_ids = ', '.join([d.id for d in deployments])
Expand Down
14 changes: 14 additions & 0 deletions connect_ext_ppr/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
DeploymentSchema,
FileSchema,
HubSchema,
MarketplaceSchema,
PPRVersionReferenceSchema,
ProductSchema,
)
Expand Down Expand Up @@ -492,3 +493,16 @@ def process_ppr(wb, product, config_json, items):
ws_list.append(ws)

return ws_list, summary


def get_marketplace_schema(marketplace, ppr):
mp_schema = MarketplaceSchema(
id=marketplace['id'],
name=marketplace['name'],
icon=marketplace['icon'],
external_id=marketplace.get('external_id'),
)
if ppr:
mp_schema.ppr = PPRVersionReferenceSchema(id=ppr.id, version=ppr.version)

return mp_schema
38 changes: 36 additions & 2 deletions connect_ext_ppr/webapp.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,16 @@
from fastapi import Depends, Request, Response, status
from sqlalchemy import exists
from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.orm import joinedload
from sqlalchemy.orm import joinedload, selectinload

from connect_ext_ppr.db import create_db, get_db, VerboseBaseSession
from connect_ext_ppr.errors import ExtensionHttpError
from connect_ext_ppr.models.configuration import Configuration
from connect_ext_ppr.models.deployment import Deployment, DeploymentRequest
from connect_ext_ppr.models.deployment import (
Deployment,
DeploymentRequest,
MarketplaceConfiguration,
)
from connect_ext_ppr.models.enums import ConfigurationStateChoices, DeploymentStatusChoices
from connect_ext_ppr.models.file import File
from connect_ext_ppr.models.replicas import Product
Expand All @@ -36,6 +40,7 @@
DeploymentRequestSchema,
DeploymentSchema,
HubSchema,
MarketplaceSchema,
ProductSchema,
)
from connect_ext_ppr.utils import (
Expand All @@ -50,6 +55,8 @@
get_deployment_request_schema,
get_deployment_schema,
get_hubs,
get_marketplace_schema,
get_marketplaces,
get_user_data_from_auth_token,
)

Expand Down Expand Up @@ -312,6 +319,33 @@ def remove_configuration(

return Response(status_code=204)

@router.get(
'/deployments/{deployment_id}/marketplaces',
summary="Deployment's marketplaces",
response_model=List[MarketplaceSchema],
)
def get_marketplaces_by_deployment(
self,
deployment_id: str,
client: ConnectClient = Depends(get_installation_client),
db: VerboseBaseSession = Depends(get_db),
installation: dict = Depends(get_installation),
):
get_deployment_by_id(deployment_id, db, installation)

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

mkplc_ids = [m.marketplace for m in mkplc_configs]

marketplaces = get_marketplaces(client, mkplc_ids)
response_list = []
for mkplc_config in mkplc_configs:
m_data = filter_object_list_by_id(marketplaces, mkplc_config.marketplace)
response_list.append(get_marketplace_schema(m_data, mkplc_config.ppr))
return response_list

@router.get(
'/products',
summary='List all products availables for account',
Expand Down
66 changes: 66 additions & 0 deletions tests/api/test_deployments.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import copy

from connect.eaas.core.constants import PROXIED_CONNECT_API_ATTR_NAME


Expand Down Expand Up @@ -155,3 +157,67 @@ def test_get_deployment_not_found(
'Object `DPL-YYY-YYY` not found.',
],
}


def test_get_deployments_marketplaces(
mocker,
installation,
api_client,
marketplace,
deployment_factory,
marketplace_config_factory,
ppr_version_factory,
):
m1 = marketplace
m2 = copy.deepcopy(marketplace)
m2['id'] = 'MP-123-123'
m3 = copy.deepcopy(marketplace)
m3['id'] = 'MP-123-123'
marketplaces = [m1, m2]

mocker.patch(
'connect_ext_ppr.webapp.get_marketplaces',
return_value=marketplaces,
)
deployment = deployment_factory(account_id=installation['owner']['id'])
another_dep = deployment_factory(account_id='PA-123-123')
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=another_dep, marketplace_id=m3['id'])

response = api_client.get(
f'/api/deployments/{deployment.id}/marketplaces',
installation=installation,
)

assert response.status_code == 200

expected_response = [
{
'id': m['id'],
'name': m['name'],
'icon': m['icon'],
} for m in marketplaces
]

expected_response[0].update({'ppr': {'id': ppr.id, 'version': ppr.version}})
assert response.json() == expected_response


def test_get_deployments_marketplaces_not_accounts_deployment(
installation,
api_client,
marketplace,
deployment_factory,
marketplace_config_factory,
):
deployment = deployment_factory(account_id="INVALID")
marketplace_config_factory(deployment=deployment, marketplace_id=marketplace['id'])

response = api_client.get(
f'/api/deployments/{deployment.id}/marketplaces',
installation=installation,
)

assert response.status_code == 404
21 changes: 20 additions & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@
VerboseBaseSession,
)
from connect_ext_ppr.models.configuration import Configuration
from connect_ext_ppr.models.deployment import Deployment, DeploymentRequest
from connect_ext_ppr.models.deployment import (
Deployment,
DeploymentRequest,
MarketplaceConfiguration,
)
from connect_ext_ppr.models.file import File
from connect_ext_ppr.models.ppr import PPRVersion
from connect_ext_ppr.models.replicas import Product
Expand Down Expand Up @@ -256,6 +260,21 @@ def _build_file(
return _build_file


@pytest.fixture
def marketplace_config_factory(dbsession, ppr_version_factory):
def _build_mc(deployment, marketplace_id, ppr_id=None):
mp = MarketplaceConfiguration(
deployment=deployment.id,
marketplace=marketplace_id,
ppr_id=ppr_id,
)
dbsession.add(mp)
dbsession.commit()
dbsession.refresh(mp)
return mp
return _build_mc


@pytest.fixture
def file(file_factory):
return file_factory()
Expand Down
43 changes: 41 additions & 2 deletions tests/test_service.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import copy
import json

from sqlalchemy import null
from connect.client import ClientError
import pytest

from connect_ext_ppr.models.deployment import Deployment
from connect_ext_ppr.models.deployment import Deployment, MarketplaceConfiguration
from connect_ext_ppr.models.file import File
from connect_ext_ppr.schemas import FileSchema, PPRCreateSchema
from connect_ext_ppr.service import add_deployments, create_ppr, get_ppr_new_version


def test_add_deployments(
def test_add_one_deployments(
dbsession,
listing,
marketplace,
Expand All @@ -29,6 +31,43 @@ def test_add_deployments(
assert new_dep is not None


def test_add_mutiples_deployments(
dbsession,
listing,
marketplace,
product,
installation,
logger,
):
mkplc_husb = []
hub_id = 'HB-1111-2222'
listing['contract']['marketplace'] = marketplace
listing['contract']['marketplace']['hubs'][0]['hub']['id'] = hub_id
listing['product'] = product

for hub in marketplace['hubs']:
mkplc_husb.append((marketplace['id'], hub['hub']['id']))

listing2 = copy.deepcopy(listing)
listing2['contract']['marketplace']['id'] = 'MP-1234'
listing2['contract']['marketplace']['hubs'][0]['hub']['id'] = 'HB-1234-1234'

for hub in listing2['contract']['marketplace']['hubs']:
mkplc_husb.append((listing2['contract']['marketplace']['id'], hub['hub']['id']))

add_deployments(installation, [listing, listing2], {}, logger)
assert dbsession.query(Deployment).count() == 3
assert dbsession.query(MarketplaceConfiguration).count() == 4

for marketplace_id, hub_id in mkplc_husb:
new_dep = dbsession.query(Deployment).filter_by(hub_id=hub_id).first()
assert new_dep is not None
assert dbsession.query(MarketplaceConfiguration).filter_by(
deployment=new_dep.id,
marketplace=marketplace_id,
).filter(MarketplaceConfiguration.id.is_not(null())).count() == 1


def test_nothing_to_create(
dbsession,
listing,
Expand Down