import rift.package.cloud_init
import rift.package.script
import rift.mano.dts as mano_dts
+import rift.mano.utils.short_name as mano_short_name
class VMResourceError(Exception):
loop,
vdud,
vnfr,
+ nsr_config,
mgmt_intf,
mgmt_network,
cloud_account_name,
self._loop = loop
self._vdud = vdud
self._vnfr = vnfr
+ self._nsr_config = nsr_config
self._mgmt_intf = mgmt_intf
self._cloud_account_name = cloud_account_name
self._vnfd_package_store = vnfd_package_store
""" Return this VDUR's name """
return self._name
+ # Truncated name confirming to RFC 1123
+ @property
+ def unique_short_name(self):
+ """ Return this VDUR's unique short name """
+ # Impose these restrictions on Unique name
+ # Max 64
+ # - Max 10 of NSR name (remove all specialcharacters, only numbers and alphabets)
+ # - 6 chars of shortened name
+ # - Max 10 of VDU name (remove all specialcharacters, only numbers and alphabets)
+ #
+ def _restrict_tag(input_str):
+ # Exclude all characters except a-zA-Z0-9
+ outstr = re.sub('[^a-zA-Z0-9]', '', input_str)
+ # Take max of 10 chars
+ return outstr[-10:]
+
+ # Use NSR name for part1
+ part1 = _restrict_tag(self._nsr_config.name)
+ # Get unique short string (6 chars)
+ part2 = mano_short_name.StringShortner(self._name)
+ # Use VDU ID for part3
+ part3 = _restrict_tag(self._vdud.id)
+ shortstr = part1 + "-" + part2.short_string + "-" + part3
+ return shortstr
+
@property
def cloud_account_name(self):
""" Cloud account this VDU should be created in """
"hypervisor_epa",
"host_epa",
"volumes",
- "name"]
+ ]
vdu_copy_dict = {k: v for k, v in
self._vdud.as_dict().items() if k in vdu_fields}
vdur_dict = {"id": self._vdur_id,
"vdu_id_ref": self._vdud.id,
"operational_status": self.operational_status,
"operational_status_details": self._state_failed_reason,
+ "name": self.name,
+ "unique_short_name": self.unique_short_name
}
+
if self.vm_resp is not None:
vdur_dict.update({"vim_id": self.vm_resp.vdu_id,
"flavor_id": self.vm_resp.flavor_id
try:
return cloud_init_extractor.read_script(stored_package, filename)
except rift.package.cloud_init.CloudInitExtractionError as e:
+ self.instantiation_failed(str(e))
raise VirtualDeploymentUnitRecordError(e)
else:
self._log.debug("VDU Instantiation: cloud-init script not provided")
vdu_copy_dict = {k: v for k, v in self._vdud.as_dict().items() if k in vdu_fields}
vm_create_msg_dict = {
- "name": self.name,
+ "name": self.unique_short_name, # Truncated name confirming to RFC 1123
+ "node_id": self.name, # Rift assigned Id
}
if self.image_name is not None:
cp_list = []
for intf, cp, vlr in self._ext_intf:
- cp_info = {"name": cp.name,
- "virtual_link_id": vlr.network_id,
- "type_yang": intf.virtual_interface.type_yang,
- "port_security_enabled": cp.port_security_enabled}
+ cp_info = { "name": cp.name,
+ "virtual_link_id": vlr.network_id,
+ "type_yang": intf.virtual_interface.type_yang }
+
+ if cp.has_field('port_security_enabled'):
+ cp_info["port_security_enabled"] = cp.port_security_enabled
if (intf.virtual_interface.has_field('vpci') and
intf.virtual_interface.vpci is not None):
"type_yang": intf.virtual_interface.type_yang,
"vpci": intf.virtual_interface.vpci})
else:
- cp_list.append({"name": cp,
- "virtual_link_id": vlr.network_id,
- "type_yang": intf.virtual_interface.type_yang,
- "port_security_enabled": cp.port_security_enabled})
+ if cp.has_field('port_security_enabled'):
+ cp_list.append({"name": cp,
+ "virtual_link_id": vlr.network_id,
+ "type_yang": intf.virtual_interface.type_yang,
+ "port_security_enabled": cp.port_security_enabled})
+ else:
+ cp_list.append({"name": cp,
+ "virtual_link_id": vlr.network_id,
+ "type_yang": intf.virtual_interface.type_yang})
+
vm_create_msg_dict["connection_points"] = cp_list
vm_create_msg_dict.update(vdu_copy_dict)
vm_resp = yield from self.create_resource(xact, vnfr, config)
self._vm_resp = vm_resp
-
self._state = VDURecordState.RESOURCE_ALLOC_PENDING
+
self._log.debug("Requested VM from resource manager response %s",
vm_resp)
if vm_resp.resource_state == "active":
return None
@asyncio.coroutine
- def get_vdu_placement_groups(self, vdu):
+ def get_vdu_placement_groups(self, vdu, nsr_config):
placement_groups = []
### Step-1: Get VNF level placement groups
for group in self._vnfr_msg.placement_groups_info:
#group_info.from_dict(group.as_dict())
placement_groups.append(group)
- ### Step-2: Get NSR config. This is required for resolving placement_groups cloud constructs
- nsr_config = yield from self.get_nsr_config()
-
- ### Step-3: Get VDU level placement groups
+ ### Step-2: Get VDU level placement groups
for group in self.vnfd.placement_groups:
for member_vdu in group.member_vdus:
if member_vdu.member_vdu_ref == vdu.id:
return placement_groups
+ @asyncio.coroutine
+ def vdu_cloud_init_instantiation(self):
+ [vdu.vdud_cloud_init for vdu in self._vdus]
+
@asyncio.coroutine
def create_vdus(self, vnfr, restart_mode=False):
""" Create the VDUs associated with this VNF """
self._log.info("Creating VDU's for vnfd id: %s", self.vnfd_id)
+
+ # Get NSR config - Needed for placement groups and to derive VDU short-name
+ nsr_config = yield from self.get_nsr_config()
+
for vdu in self._rw_vnfd.vdu:
self._log.debug("Creating vdu: %s", vdu)
vdur_id = get_vdur_id(vdu)
- placement_groups = yield from self.get_vdu_placement_groups(vdu)
- self._log.info("Launching VDU: %s from VNFD :%s (Member Index: %s) with Placement Groups: %s",
+
+ placement_groups = yield from self.get_vdu_placement_groups(vdu, nsr_config)
+ self._log.info("Launching VDU: %s from VNFD :%s (Member Index: %s) with Placement Groups: %s, Existing vdur_id %s",
vdu.name,
self.vnf_name,
self.member_vnf_index,
- [ group.name for group in placement_groups])
+ [ group.name for group in placement_groups],
+ vdur_id)
vdur = VirtualDeploymentUnitRecord(
dts=self._dts,
loop=self._loop,
vdud=vdu,
vnfr=vnfr,
+ nsr_config=nsr_config,
mgmt_intf=self.has_mgmt_interface(vdu),
mgmt_network=self._mgmt_network,
cloud_account_name=self.cloud_account_name,
vdu_id_pattern = re.compile(r"\{\{ vdu\[([^]]+)\]\S* \}\}")
for vdu in self._vdus:
- if vdu.vdud_cloud_init is not None:
- for vdu_id in vdu_id_pattern.findall(vdu.vdud_cloud_init):
+ if vdu._vdud_cloud_init is not None:
+ for vdu_id in vdu_id_pattern.findall(vdu._vdud_cloud_init):
if vdu_id != vdu.vdu_id:
# This means that vdu.vdu_id depends upon vdu_id,
# i.e. vdu_id must be instantiated before
# wait for the VDUR to enter a terminal state
while vdu._state not in terminal:
yield from asyncio.sleep(1, loop=self._loop)
-
# update the datastore
datastore.update(vdu)
self._log.debug("VNFR-ID %s: Publish VNFR", self._vnfr_id)
yield from self.publish(xact)
+
# instantiate VLs
- self._log.debug("VNFR-ID %s: Instantiate VLs", self._vnfr_id)
+ self._log.debug("VNFR-ID %s: Instantiate VLs, restart mode %s", self._vnfr_id, restart_mode)
try:
yield from self.instantiate_vls(xact, restart_mode)
except Exception as e:
self.set_state(VirtualNetworkFunctionRecordState.VM_INIT_PHASE)
# instantiate VDUs
- self._log.debug("VNFR-ID %s: Create VDUs", self._vnfr_id)
+ self._log.debug("VNFR-ID %s: Create VDUs, restart mode %s", self._vnfr_id, restart_mode)
yield from self.create_vdus(self, restart_mode)
+ try:
+ yield from self.vdu_cloud_init_instantiation()
+ except Exception as e:
+ self.set_state(VirtualNetworkFunctionRecordState.FAILED)
+ self._state_failed_reason = str(e)
+ yield from self.publish(xact)
+
# publish the VNFR
self._log.debug("VNFR-ID %s: Publish VNFR", self._vnfr_id)
yield from self.publish(xact)
if action == rwdts.QueryAction.READ:
schema = RwVnfrYang.YangData_RwVnfr_VnfrConsole_Vnfr_Vdur.schema()
path_entry = schema.keyspec_to_entry(ks_path)
- self._log.debug("VDU Opdata path is {}".format(path_entry))
+ self._log.debug("VDU Opdata path is {}".format(path_entry.key00.id))
try:
vnfr = self._vnfm.get_vnfr(self._vnfr_id)
except VnfRecordError as e:
set_if_not_none('name', vdur._vdud.name)
set_if_not_none('mgmt.ip', vdur.vm_management_ip)
+ # The below can be used for hostname
+ set_if_not_none('vdur_name', vdur.unique_short_name)
def update(self, vdur):
"""Update the VDUR information in the datastore
set_or_delete('name', vdur._vdud.name)
set_or_delete('mgmt.ip', vdur.vm_management_ip)
+ # The below can be used for hostname
+ set_or_delete('vdur_name', vdur.unique_short_name)
def remove(self, vdur_id):
"""Remove all of the data associated with specified VDUR