Skip to content
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
18 changes: 18 additions & 0 deletions partnercenter/azext_partnercenter/_headers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------


from azext_partnercenter.version import VERSION


USER_AGENT_HEADER = {'User-Agent': f"AzureCLI-PCExt/{VERSION}"}


def add_user_agent_header(set_headers_func):
"""Adds the user agent header to the headers dictionary."""
if set_headers_func is None or not callable(set_headers_func):
raise ValueError("set_headers_func must be a callable function.")
key_name = list(USER_AGENT_HEADER.keys())[0]
set_headers_func(key_name, USER_AGENT_HEADER[key_name])
1 change: 0 additions & 1 deletion partnercenter/azext_partnercenter/_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ def _load_operations_help():
'marketplace_offer_plan',
'marketplace_offer_plan_listing',
'marketplace_offer_plan_technicalconfiguration',
'marketplace_offer_setup',
'marketplace_offer_submission'
]
for module_name in operations_modules:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@

# pylint: disable=line-too-long
# pylint: disable=protected-access


from azext_partnercenter._headers import add_user_agent_header


def get_api_client(cli_ctx, *_):
"""Gets an instance of an sdk client"""
# subscription_id = cli_ctx.data['subscription_id']
Expand All @@ -22,6 +27,7 @@ def get_api_client(cli_ctx, *_):
# set authorixation header to the raw token credentials fetched
api_client.set_default_header("Authorization", creds[0] + " " + creds[1])
api_client.set_default_header("If-Match", "*")
add_user_agent_header(api_client.set_default_header)

return api_client

Expand All @@ -41,5 +47,6 @@ def get_api_client_for_graph(cli_ctx, *_):
# set authorixation header to the raw token credentials fetched
api_client.set_default_header("Authorization", creds[0] + " " + creds[1])
api_client.set_default_header("If-Match", "*")
add_user_agent_header(api_client.set_default_header)

return api_client
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

from time import time
import requests
from pydantic import Extra
from azext_partnercenter._headers import USER_AGENT_HEADER
from azext_partnercenter.vendored_sdks.production_ingestion.models import (
Submission,
ContainerPlanTechnicalConfiguration,
Expand Down Expand Up @@ -48,7 +48,9 @@ class ProductIngestionApiClient:
"""The Product Ingestion API client"""
def __init__(self, access_token=None):
self.configuration = ProductIngestionApiClientConfiguration(access_token=access_token)
self._default_headers = {'Accept': 'application/json'}

# User-Agent header value is used by marketplace eng to identify the client making the request
self._default_headers = {'Accept': 'application/json', **USER_AGENT_HEADER}

def configure_resources(self, *resources):
"""Configures one or more resources
Expand All @@ -59,7 +61,7 @@ def configure_resources(self, *resources):
operation_id = 'post-configure'
configure_resources = ConfigureResources(resources=resources)
data = configure_resources.dict(by_alias=True, exclude_unset=True)
data['$schema'] = 'https://product-ingestion.azureedge.net/schema/configure/2022-03-01-preview2'
data['$schema'] = 'https://schema.mp.microsoft.com/schema/configure/2022-03-01-preview2'

for resource in data['resources']:
if 'resourceName' in resource.keys():
Expand All @@ -70,7 +72,7 @@ def configure_resources(self, *resources):
response = self.__call_api(operation_id, 'configure', data=data)
response.raise_for_status()

ConfigureResourcesStatus.Config.extra = Extra.allow
ConfigureResourcesStatus.model_config = {'extra': 'allow'}
status = ConfigureResourcesStatus.parse_obj(response.json())

if status.job_status != JobStatus.completed:
Expand Down Expand Up @@ -102,7 +104,7 @@ def update_container_plan_technical_configuration_for_bundle(self, offer_durable
setattr(configuration, 'cnabReferences', properties.cnab_references)

resource = configuration.dict(by_alias=True)
resource['$schema'] = 'https://product-ingestion.azureedge.net/schema/container-plan-technical-configuration/2022-03-01-preview3'
resource['$schema'] = 'https://schema.mp.microsoft.com/schema/container-plan-technical-configuration/2022-03-01-preview3'

del resource['resourceName']
del resource['validations']
Expand Down Expand Up @@ -136,7 +138,7 @@ def publish_submission(self, target, offer_durable_id, submission_id=None):
durable_id = DurableId(root=f"submission/{offer_durable_id}/{submission_id}") if submission_id is not None else None

resource = {
'$schema': 'https://product-ingestion.azureedge.net/schema/submission/2022-03-01-preview2',
'$schema': 'https://schema.mp.microsoft.com/schema/submission/2022-03-01-preview2',
'id': (None if durable_id is None else durable_id.root),
'product': product_id.root,
'target': {'targetType': target}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

# pylint: disable=line-too-long
# pylint: disable=protected-access
# pylint: disable=too-many-positional-arguments

from azext_partnercenter.models.listing_image import ListingImage
from azext_partnercenter.models.listing_video import ListingVideo
Expand Down
6 changes: 5 additions & 1 deletion partnercenter/azext_partnercenter/clients/offer_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,14 @@ def _map_product_to_offer(self, product):
resource=Resource(durable_id=product.id, type=product.resource_type)
)

# removed
def get_setup(self, offer_external_id):
offer = self.get(offer_external_id)
result = self._sdk.product_client.products_product_id_setup_get(offer.resource.durable_id, self._get_access_token())
print(result)
return self._map_setup(offer_external_id, result)

# removed
def update_setup(self, parameters: OfferSetup):
offer = self.get(parameters.id)

Expand Down Expand Up @@ -106,6 +109,7 @@ def update_setup(self, parameters: OfferSetup):
offer_setup = self.get_setup(parameters.id)
return offer_setup

# removed
def _map_setup(self, offer_external_id, api_setup: MicrosoftIngestionApiModelsProductsAzureProductSetup) -> OfferSetup:
reseller = (next((x for x in api_setup.channel_states if x['type'] == "Reseller"), None))['value'] == 'Enabled'
sell_through_microsoft = api_setup.selling_option == 'ListAndSell'
Expand Down Expand Up @@ -171,7 +175,7 @@ def _get_sdk_product_by_external_offer_id(self, offer_external_id):
"""Package Internal helper method to get the SDK product object by Offer ID"""
filter_expr = self._get_sdk_odata_filter_expression_by_external_offer_id(offer_external_id)
products = self._sdk.product_client.products_get(self._get_access_token(), filter=filter_expr)
print(f"products is {products}")

if products is None or len(products.value) == 0:
return None

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,14 @@ def get(self, offer_external_id, submission_id):
offer = self._offer_client.get(offer_external_id)

if offer.type == "AzureContainer":
result = self._graph_api_client.get_submission(submission_id, offer.resource.durable_id)
result = self._graph_api_client.get_submission(offer.resource.durable_id, submission_id)
return self._map_submission(result)

if offer.type == "AzureApplication":
result = self._sdk.submission_client.products_product_id_submissions_submission_id_get(offer.resource.durable_id, submission_id, self._get_access_token())
return self._map_application_submission(result)

raise CLIError("Only AzureContainer and AzureApplication offers are supported for submission commands")
raise CLIError("Only AzureContainer and AzureApplication offers are supported for submission commands at this time")

def list(self, offer_external_id):
offer = self._offer_client.get(offer_external_id)
Expand All @@ -51,7 +51,7 @@ def list(self, offer_external_id):
result = self._sdk.submission_client.products_product_id_submissions_get(offer.resource.durable_id, self._get_access_token())
return list(map(self._map_application_submission, result.value))

raise CLIError("Only AzureContainer and AzureApplication offers are supported for submission commands")
raise CLIError("Only AzureContainer and AzureApplication offers are supported for submission commands at this time")

def _get_offer_draft_instance(self, offer_durable_id, module):
branches = self._sdk.branches_client.products_product_id_branches_get_by_module_modulemodule_get(
Expand Down Expand Up @@ -211,12 +211,12 @@ def _get_resources_and_variant_resources(self, durable_id, managed_application_v

@staticmethod
def _map_submission(s: MicrosoftIngestionApiModelsSubmissionsSubmission) -> OfferSubmission:
print(f"Mapping submission {s}")
return OfferSubmission(
id=s.id.root.split('/')[-1],
# lifecycle_state=s.substate,
# target=s.target.target_type,
# status=s.state,
# result=s.result,
created=s.published_time_in_utc
offer_id=s.product.root.root.split('/')[-1],
lifecycle_state=s.lifecycle_state,
target=s.target.target_type,
status=s.status,
result=s.result,
created=s.created
)
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
# pylint: disable=line-too-long
# pylint: disable=protected-access
# pylint: disable=no-else-return
# pylint: disable=too-many-positional-arguments

import os
from knack.util import CLIError
Expand Down
2 changes: 0 additions & 2 deletions partnercenter/azext_partnercenter/operations/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
from azext_partnercenter.operations.marketplace_offer_listing_contact import MarketplaceOfferListingContactOperations
from azext_partnercenter.operations.marketplace_offer_listing_uri import MarketplaceOfferListingUriOperations
from azext_partnercenter.operations.marketplace_offer_listing import MarketplaceOfferListingOperations
from azext_partnercenter.operations.marketplace_offer_setup import MarketplaceOfferSetupOperations
from azext_partnercenter.operations.marketplace_offer_listing_media import MarketplaceOfferListingImageOperations
from azext_partnercenter.operations.marketplace_offer_package import MarketplaceOfferPackageOperations
from azext_partnercenter.operations.marketplace_offer_submission import MarketplaceOfferSubmissionOperations
Expand All @@ -25,7 +24,6 @@ def __init__(self, commands_loader):
MarketplaceOfferPlanOperations(self),
MarketplaceOfferPlanTechnicalConfigurationOperations(self),
MarketplaceOfferListingOperations(self),
MarketplaceOfferSetupOperations(self),
MarketplaceOfferPackageOperations(self),
MarketplaceOfferSubmissionOperations(self),
MarketplaceOfferPlanListingOperations(self),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------
# pylint: disable=line-too-long
# pylint: disable=too-many-positional-arguments

from azure.cli.core.azclierror import ResourceNotFoundError
from azext_partnercenter.models.listing_contact import ListingContact
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
# --------------------------------------------------------------------------------------------
# pylint: disable=too-many-locals
# pylint: disable=line-too-long
# pylint: disable=too-many-positional-arguments

from knack.util import CLIError
from azext_partnercenter.models.listing_uri import ListingUri
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------
# pylint: disable=raise-missing-from
# pylint: disable=too-many-positional-arguments

import os
import os.path
Expand All @@ -16,15 +17,30 @@

def verify(manifest_file):
container = _get_container(manifest_file)
result = container.exec_run('cpa verify', workdir=DATA_DIR)
return result

if container.status != 'running':
container.start()

result = container.exec_run('cpa verify', workdir=DATA_DIR, stream=True)
for output in result.output:
print(output.decode("utf-8"), end='')

container.stop()


def bundle(manifest_file):
container = _get_container(manifest_file)

if container.status != 'running':
container.start()

acr_name = _get_acr_name(manifest_file)
result = container.exec_run('az acr login -n ' + acr_name)
result = container.exec_run('cpa buildbundle', workdir=DATA_DIR)
container.exec_run('az acr login -n ' + acr_name)
result = container.exec_run('cpa buildbundle', workdir=DATA_DIR, stream=True)
for output in result.output:
print(output.decode("utf-8"), end='')

container.stop()
return result


Expand All @@ -37,7 +53,7 @@ def _get_container(manifest_file):
mount_path = _get_mount_path(manifest_file)
container = _run_container(container_name, mount_path)
except:
raise CLIError('There was an unknow error when trying to find the cpacontainer')
raise CLIError('There was an unknown error when trying to find the cpacontainer')
return container


Expand All @@ -51,7 +67,12 @@ def _run_container(container_name, mount_path):

print(mount_path)

if client.images.list(name=img) == []:
print(f"Image {img} not found. Pulling the image...")
client.images.pull(img)

volumes = ['/var/run/docker.sock:/var/run/docker.sock', f'{mount_path}:/data', f'{absolute_path}:/root/.azure']

container = client.containers.run(img, cmd, detach=True, volumes=volumes, name=container_name)
return container

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------
# pylint: disable=line-too-long
# pylint: disable=too-many-positional-arguments

from azure.cli.core.azclierror import ResourceNotFoundError, InvalidArgumentValueError
from knack.cli import CLIError
Expand Down Expand Up @@ -66,12 +67,8 @@ def _build_container_package_by_offer_type(client, offer_id, manifest_file, acti


def _verify_cnab_bundle(manifest_file):
result = verify(manifest_file)
print(result.output.decode("utf-8"))
return result
verify(manifest_file)


def _build_cnab_bundle(manifest_file):
result = bundle(manifest_file)
print(result.output.decode("utf-8"))
return result
bundle(manifest_file)
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------
# pylint: disable=line-too-long
# pylint: disable=too-many-positional-arguments

from knack.cli import CLIError
from azext_partnercenter.vendored_sdks.production_ingestion.models import (ContainerCnabPlanTechnicalConfigurationProperties, CnabReference)
from azext_partnercenter import ISSUES_URL
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def load_arguments(commands_loader, _):
c.argument('registry_name', arg_group='CNAB Resource', options_list=['--registry'], help='The name of the Azure Container Registry.')
c.argument('repository_name', arg_group='CNAB Resource', options_list=['--repository'], help='The name of the image repository in the Azure Container Registry.')
c.argument('tag', arg_group='CNAB Resource', options_list=['--tag'], help='The name of the image repository.')
c.argument('digest', arg_group='CNAB Resource', options_list=['--digest'], help='The digest of the bundle with a format of sha256:<hashcode>')
c.argument('digest', arg_group='CNAB Resource', options_list=['--digest'], help='The digest of the bundle with a format of sha256:hashcode')
c.argument('package_path', options_list=['--package-path'], help='The full path to the package zip file')
c.argument('public_azure_tenant_id', options_list=['--azure-tenant-id'], help='The public Azure Tenant ID of the account that will managed the package')
c.argument('public_azure_authorization_principal', options_list=['--azure-auth-principal'], help='The principal that will managed the package when deployed to public Azure')
Expand Down

This file was deleted.

This file was deleted.

Loading