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
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def run(self, tmp=None, task_vars=None):
update_status_code = [201]

before = current_product
after = product.dict()
after = product.dict(exclude_none=True)

# These are generated by apigee outside our control so it
# makes no sense to include them in the delta.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
from typing import Optional
import pydantic


class ApigeeApidoc(pydantic.BaseModel):
edgeAPIProductName: str
anonAllowed: bool
description: str
requireCallbackUrl: bool
title: str
visibility: bool
anonAllowed: bool = True
description: str = None
requireCallbackUrl: bool = False
title: str = None
visibility: bool = False
specId: str = ""
specContent: str = ""

class Config:
extra = "forbid"
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
ValidationError,
constr,
conint,
conlist,
validator,
root_validator,
)
Expand All @@ -14,7 +15,17 @@
RateLimitingConfig,
)


LITERAL_APIGEE_ENVIRONMENTS = Literal[
"internal-dev",
"internal-dev-sandbox",
"internal-qa",
"internal-qa-sandbox",
"ref",
"dev",
"sandbox",
"int",
"prod",
]
MANUAL_APPROVAL_EXCEPTIONS = ["canary-api-prod"]


Expand Down Expand Up @@ -110,23 +121,32 @@ def _count_cls(items: List[Any], cls: Type):

class ApigeeProduct(BaseModel):
name: str
approvalType: Literal["auto", "manual"]
approvalType: Literal["auto", "manual"] = "manual"
attributes: List[
Union[
ApigeeProductAttributeAccess,
ApigeeProductAttributeRateLimit,
ApigeeProductAttributeRateLimiting,
ApigeeProductAttribute,
],
]
description: str
displayName: str
environments: List[str]
proxies: List[str]
quota: constr(regex=r"[1-9][0-9]*")
quotaInterval: constr(regex=r"[1-9][0-9]*")
quotaTimeUnit: Literal["minute", "hour"]
scopes: List[str]
] = [{"name": "access", "value": "private"}]
description: str = None
displayName: str = None

# Note: This value is manually inserted by apigee_environment
# object that contains this product. So if you do not provide a
# value in the manifest file it is still populated.
environments: conlist(
item_type=LITERAL_APIGEE_ENVIRONMENTS, min_items=1, max_items=1
)
proxies: List[str] = []
quota: constr(regex=r"[1-9][0-9]*") = None
quotaInterval: constr(regex=r"[1-9][0-9]*") = None
quotaTimeUnit: Literal["minute", "hour"] = None
scopes: List[str] = []

class Config:
extra = "forbid"

@root_validator
def override_approval_type_for_prod(cls, values):
Expand All @@ -136,7 +156,7 @@ def override_approval_type_for_prod(cls, values):
values["approvalType"] = "manual"
return values

@validator("environments", "scopes", "proxies")
@validator("environments", "scopes", "proxies", check_fields=False)
def sorted(cls, v):
return sorted(v)

Expand All @@ -146,7 +166,7 @@ def validate_attributes(cls, attributes, values):

class_min_max = [
(ApigeeProductAttributeAccess, 1, 1),
(ApigeeProductAttributeRateLimit, 1, 1),
(ApigeeProductAttributeRateLimit, 0, 1),
(ApigeeProductAttributeRateLimiting, 0, 1),
]

Expand All @@ -164,3 +184,24 @@ def validate_attributes(cls, attributes, values):
)

return attributes

@validator("proxies", always=True)
def ensure_identity_service(cls, proxies, values):
"""
We never want to deploy products with no proxies, as that
allows access to absolutely everything in the apigee
organization.

This validator will inject the identity-service for the
environment if the list of proxies is empty.
"""
if len(proxies) == 0:
env = values["environments"][0]
return [f"identity-service-{env}"]
return proxies

@validator("displayName", always=True)
def validate_display_name(cls, displayName, values):
if not displayName:
return values["name"]
return displayName
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,6 @@ def dict(self, **kwargs):
if native.get("guid"):
native.update({"guid": str(native["guid"])})
return native

class Config:
extra = "forbid"
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,12 @@
)
from ansible_collections.nhsd.apigee.plugins.module_utils.models.apigee.product import (
ApigeeProduct,
LITERAL_APIGEE_ENVIRONMENTS
)


class ManifestApigeeEnvironment(pydantic.BaseModel):
name: typing.Literal[
"internal-dev",
"internal-dev-sandbox",
"internal-qa",
"internal-qa-sandbox",
"ref",
"dev",
"sandbox",
"int",
"prod",
]
name: LITERAL_APIGEE_ENVIRONMENTS
products: typing.List[ApigeeProduct]
specs: typing.List[ApigeeSpec]
api_catalog: typing.List[ApigeeApidoc]
Expand All @@ -49,3 +40,14 @@ def catalog_references(cls, api_catalog, values):
f"specId {item.specId} not in list of specs in this environment"
)
return api_catalog

@pydantic.validator("products", pre=True)
def set_single_environment(cls, products, values):
"""
Manually set the product environments to match manifest
environment.
"""
env = values["name"]
for i in range(len(products)):
products[i]["environments"] = [env]
return products
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from ansible_collections.nhsd.apigee.plugins.module_utils.paas import api_registry

SCHEMA_VERSION = "1.1.2"
SCHEMA_VERSION = "1.1.3"

_REGISTRY_DATA = {}

Expand Down
Loading