from typing import Any
from idem_vra.helpers.mapper import add_properties
from idem_vra.helpers.mapper import omit_properties
from idem_vra.helpers.models import StateReturn
__contracts__ = ["resource"]
TREQ = {
"present": {"require": ["vra.iaas.location.present"]},
"absent": {"require": []},
}
[docs]async def present(hub, ctx, name: str, regionId: Any, **kwargs):
"""
:param string regionId: (required in body) The Id of the region for which this profile is created
:param string name: (required in body) A human-friendly name used as an identifier in APIs that support this
option.
:param string apiVersion: (optional in query) The version of the API in yyyy-MM-dd format (UTC). For versioning
information refer to /iaas/api/about
:param string description: (optional in body) A human-friendly description.
:param string isolationNetworkDomainCIDR: (optional in body) CIDR of the isolation network domain.
:param string isolationNetworkDomainId: (optional in body) The Id of the network domain used for creating isolated networks.
:param array tags: (optional in body) A set of tag keys and optional values that should be set on any
resource that is produced from this specification.
:param array externalIpBlockIds: (optional in body) List of external IP blocks coming from an external IPAM provider that
can be used to create subnetworks inside them
:param array fabricNetworkIds: (optional in body) A list of fabric network Ids which are assigned to the network
profile.
:param object customProperties: (optional in body) Additional properties that may be used to extend the Network Profile
object that is produced from this specification. For isolationType
security group, datastoreId identifies the Compute Resource Edge
datastore. computeCluster and resourcePoolId identify the Compute
Resource Edge cluster. For isolationType subnet,
distributedLogicalRouterStateLink identifies the on-demand network
distributed local router (NSX-V only). For isolationType subnet,
tier0LogicalRouterStateLink identifies the on-demand network tier-0
logical router (NSX-T only). onDemandNetworkIPAssignmentType
identifies the on-demand network IP range assignment type static,
dynamic, or mixed.
:param array securityGroupIds: (optional in body) A list of security group Ids which are assigned to the network
profile.
:param string isolationExternalFabricNetworkId: (optional in body) The Id of the fabric network used for outbound access.
:param string isolationType: (optional in body) Specifies the isolation type e.g. none, subnet or security group
:param integer isolatedNetworkCIDRPrefix: (optional in body) The CIDR prefix length to be used for the isolated networks that are
created with the network profile.
:param array loadBalancerIds: (optional in body) A list of load balancers which are assigned to the network profile.
"""
try:
state = NetworkprofileState(hub, ctx)
return await state.present(hub, ctx, name, regionId, **kwargs)
except Exception as error:
hub.log.error("Error during enforcing present state: networkprofile")
hub.log.error(str(error))
raise error
[docs]async def absent(hub, ctx, name: str, **kwargs):
"""
:param string p_id: (required in path) The ID of the network profile.
:param string apiVersion: (optional in query) The version of the API in yyyy-MM-dd format (UTC). For versioning
information refer to /iaas/api/about
"""
"""
:param string name: (required) name of the resource
"""
try:
state = NetworkprofileState(hub, ctx)
return await state.absent(hub, ctx, name, **kwargs)
except Exception as error:
hub.log.error("Error during enforcing absent state: networkprofile")
hub.log.error(str(error))
raise error
[docs]async def describe(hub, ctx):
try:
state = NetworkprofileState(hub, ctx)
return await state.describe(hub, ctx)
except Exception as error:
hub.log.error("Error during describe: networkprofile")
hub.log.error(str(error))
raise error
[docs]def is_pending(hub, ret: dict, state: str = None, **pending_kwargs):
try:
state = NetworkprofileState(hub, None)
return state.is_pending(hub, ret, state, **pending_kwargs)
except Exception as error:
hub.log.error("Error during is_pending: networkprofile")
hub.log.error(str(error))
raise error
[docs]class NetworkprofileState:
def __init__(self, hub, ctx):
self.hub = hub
self.ctx = ctx
[docs] async def present(self, hub, ctx, name: str, regionId: Any, **kwargs):
search_result = (await self.paginate_find(hub, ctx))["ret"]
for s in search_result.content:
if name == s["name"] and True:
hub.log.info(
f'Returning resource networkprofile "{s["name"]}" due to existing resource "{name}"'
)
s = await self.remap_resource_structure(hub, ctx, s)
return StateReturn(
result=True,
comment=f"Resource networkprofile {name} already exists.",
old=s,
new=s,
)
res = (
await hub.exec.vra.iaas.networkprofile.create_network_profile(
ctx, regionId, name, **kwargs
)
)["ret"]
res = await self.remap_resource_structure(hub, ctx, res)
return StateReturn(
result=True,
comment=f"Creation of networkprofile {name} success.",
old=None,
new=res,
)
[docs] async def absent(self, hub, ctx, name: str, **kwargs):
search_result = (await self.paginate_find(hub, ctx))["ret"]
resource = None
for s in search_result.content:
if name == s["name"] and True:
hub.log.info(
f'Found resource networkprofile "{s["name"]}" due to existing resource "{name}"'
)
s = await self.remap_resource_structure(hub, ctx, s)
resource = s
if resource:
# it exists!
delete_kwargs = {}
delete_kwargs["p_id"] = resource.get("id")
hub.log.debug(
f"networkprofile with name = {resource.get('name')} already exists"
)
await hub.exec.vra.iaas.networkprofile.delete_network_profile(
ctx, **delete_kwargs
)
return StateReturn(
result=True,
comment=f"Resource with name = {resource.get('name')} deleted.",
old=resource,
new=None,
)
return StateReturn(
result=True,
comment=f"Resource with name = {name} is already absent.",
old=None,
new=None,
)
[docs] async def describe(self, hub, ctx):
result = {}
res = await self.paginate_find(hub, ctx)
for obj in res.get("ret", {}).get("content", []):
# Keep track of name and id properties as they may get remapped
obj_name = obj.get("name", "unknown")
obj_id = obj.get("id", "unknown")
obj = await self.remap_resource_structure(hub, ctx, obj)
# Define props
props = [{key: value} for key, value in obj.items()]
# Build result
result[f"{obj_name}-{obj_id.split('-')[-1]}"] = {
"vra.iaas.networkprofile.present": props
}
return result
[docs] async def paginate_find(self, hub, ctx, **kwargs):
"""
Paginate through all resources using their 'find' method.
"""
res = await hub.exec.vra.iaas.networkprofile.get_network_profiles(ctx, **kwargs)
numberOfElements = res.get("ret", {}).get("numberOfElements", 0)
totalElements = res.get("ret", {}).get("totalElements", 0)
initialElements = numberOfElements
if numberOfElements != totalElements and totalElements != 0:
while initialElements < totalElements:
hub.log.debug(
f"Requesting networkprofile with offset={initialElements} out of {totalElements}"
)
pres = await hub.exec.vra.iaas.networkprofile.get_network_profiles(
ctx, skip=initialElements
)
initialElements += pres.get("ret", {}).get("numberOfElements", 0)
aggO = res.get("ret", {}).get("content", [])
aggN = pres.get("ret", {}).get("content", [])
res["ret"]["content"] = [*aggO, *aggN]
res["ret"]["numberOfElements"] = initialElements
return res
[docs] def is_pending(self, hub, ret: dict, state: str = None, **pending_kwargs):
"""
State reconciliation
"""
hub.log.debug(f'Running is_pending for resource: {ret.get("__id__", None)}...')
is_pending_result = False
hub.log.debug(
f'is_pending_result for resource "{ret.get("__id__", None)}": {is_pending_result}'
)
return is_pending_result
[docs] async def remap_resource_structure(self, hub, ctx, obj: dict) -> dict:
schema_mapper = None
# Perform resource mapping by adding properties and omitting properties.
# Property renaming is addition followed by omission.
if schema_mapper:
resource_name = "networkprofile"
hub.log.debug(f"Remapping resource {resource_name}...")
obj = await add_properties(obj, schema_mapper.get("add", []))
obj = omit_properties(obj, schema_mapper.get("omit", []))
return obj