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

[JUJU-3999] Avoid parsing endpoint for overlay offers #887

Merged
merged 10 commits into from
Jun 26, 2023
2 changes: 1 addition & 1 deletion juju/bundle.py
Original file line number Diff line number Diff line change
Expand Up @@ -1043,7 +1043,7 @@ async def run(self, context):
def __str__(self):
endpoints = ""
if self.endpoints is not None:
endpoints = ":{}".format(self.endpoints.join(","))
endpoints = ":{}".format(",".join(self.endpoints))
return "create offer {offer_name} using {application}{endpoints}".format(offer_name=self.offer_name,
application=self.application,
endpoints=endpoints)
Expand Down
34 changes: 21 additions & 13 deletions juju/controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -728,24 +728,32 @@ async def create_offer(self, model_uuid, endpoint, offer_name=None, application_
consumers.

@param endpoint: holds the application and endpoint you want to offer
@param offer_name: over ride the offer name to help the consumer
@param offer_name: override the offer name to help the consumer
@param application_name: overrides the application name in the endpoint
"""
try:
offer = parse_offer_endpoint(endpoint)
except OfferParseError as e:
log.error(e.message)
raise

if offer_name is None:
offer_name = offer.application
# If we have both the offer_name and the application_name
# then we're coming from bundle/overlays, so no need to parse the endpoint
# Also we accept endpoints without a colon (:) in the overlays
if offer_name and application_name:
o_name = offer_name
a_name = application_name
eps = {endpoint: endpoint}
else:
try:
offer = parse_offer_endpoint(endpoint)
except OfferParseError as e:
log.error(e.message)
raise

if application_name is None:
application_name = offer.application
o_name = offer_name if offer_name else offer.application
a_name = application_name if application_name else offer.application
eps = {name: name for name in offer.endpoints}

params = client.AddApplicationOffer()
params.application_name = application_name
params.endpoints = {name: name for name in offer.endpoints}
params.offer_name = offer_name
params.application_name = a_name
params.endpoints = eps
params.offer_name = o_name
params.model_tag = tag.model(model_uuid)

facade = client.ApplicationOffersFacade.from_connection(self.connection())
Expand Down
8 changes: 8 additions & 0 deletions juju/remoteapplication.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,11 @@ class ApplicationOffer(model.ModelEntity):
@property
def tag(self):
return tag.application(self.name)

@property
def offer_name(self):
return self.safe_data['offer-name']

@property
def application_name(self):
return self.safe_data['application-name']
7 changes: 7 additions & 0 deletions tests/integration/bundle/test-overlays/test-overlay4.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
description: Another overlay to create an offer
applications:
grafana:
offers:
dashboards:
endpoints:
- dashboards
6 changes: 5 additions & 1 deletion tests/integration/test_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -321,13 +321,17 @@ async def test_deploy_bundle_with_multiple_overlays_with_include_files(event_loo
bundle_yaml_path = TESTS_DIR / 'integration' / 'bundle' / 'bundle.yaml'
overlay1_path = OVERLAYS_DIR / 'test-overlay2.yaml'
overlay2_path = OVERLAYS_DIR / 'test-overlay3.yaml'
overlay3_path = OVERLAYS_DIR / 'test-overlay4.yaml'

await model.deploy(str(bundle_yaml_path), overlays=[overlay1_path, overlay2_path])
await model.deploy(str(bundle_yaml_path), overlays=[overlay1_path, overlay2_path, overlay3_path])

assert 'influxdb' not in model.applications
assert 'test' not in model.applications
assert 'memcached' not in model.applications
assert 'grafana' in model.applications
assert 'grafana' in model.application_offers
assert 'grafana' == model.application_offers['grafana'].application_name
assert 'dashboards' == model.application_offers['grafana'].offer_name


@base.bootstrapped
Expand Down