/// <summary> /// Adds a vif to the attachment. /// </summary> /// <param name="role">Role of the vif</param> /// <param name="vlanTagRange">Vlan tag range for assignment of a vlan tag to the vif</param> /// <param name="mtu">Maximum transmission unit for the vif </param> /// <param name="contractBandwidthPool">An existing contract bandwidth pool to allocate to the vif</param> /// <param name="contractBandwidth">Contract bandwidth denoting the bandwidth requested for the vif</param> /// <param name="ipv4Addresses">Ipv4 addresses to be assigned to the layer 3 vif.</param> /// <param name="tenantId">Tenant identifier denoting the tenant for which the vif is assigned</param> /// <param name="vlanTag">Vlan tag to be assigned to the vif. It not provided one will be assigned.</param> public void AddVif(int tenantId, VifRole role, VlanTagRange vlanTagRange, Mtu mtu, ContractBandwidthPool contractBandwidthPool, AttachmentBandwidth attachmentBandwidth, ContractBandwidth contractBandwidth, List <Ipv4AddressAndMask> ipv4Addresses, bool trustReceivedCosAndDscp = false, int?vlanTag = null) { // The supplied vif role must be compatible with the attachment if (role.AttachmentRole.Id != this._attachmentRoleId) { throw new AttachmentDomainException($"Vif role '{role.Name}' is not valid for attachment '{this.Name}' "); } // Attachment must be 'tagged' in order to create a vif if (!role.AttachmentRole.IsTaggedRole) { throw new AttachmentDomainException($"A Vif cannot be created for attachment '{this.Name}' because the attachment is not enabled for tagging. "); } // Supplied attachment bandwidth must match that set for the attachment if (attachmentBandwidth.Id != this._attachmentBandwidthId) { throw new AttachmentDomainException($"Attachment bandwidth '{attachmentBandwidth.BandwidthGbps}' is not valid for attachment '{this.Name}' "); } // If a vlan tag is supplied, validate that it is in the correct range if (vlanTag.HasValue) { if (vlanTag < 2 || vlanTag > 4094) { throw new AttachmentDomainException("The vlan tag must be between 2 and 4094."); } // Validate that the supplied vlan tag is unique if (this._vifs.Select(v => v.VlanTag).Contains(vlanTag.Value)) { throw new AttachmentDomainException($"Vlan tag '{vlanTag}' is already used."); } } else { // Assign a free vlan tag from the supplied range vlanTag = AssignVlanTag(vlanTagRange); } var vlans = CreateVlans(role.AttachmentRole, ipv4Addresses); if (contractBandwidthPool == null && contractBandwidth == null) { throw new AttachmentDomainException("Either a contract bandwidth or an existing contract bandwidth pool is needed to create a vif."); } if (contractBandwidthPool != null) { // Validate the contract bandwidth pool belongs to this attachment if (!this.GetContractBandwidthPools().Contains(contractBandwidthPool)) { throw new AttachmentDomainException($"The supplied contract bandwidth pool does not exist or does not belong to " + "attachment '{this.Name}'."); } } if (contractBandwidth != null) { // Validate there is sufficient attachment bandwidth available var usedBandwidthMbps = this._vifs.Select(v => v.ContractBandwidthPool.ContractBandwidth.BandwidthMbps).Sum(); var availableBandwidthMbps = attachmentBandwidth.BandwidthGbps * 1000 - usedBandwidthMbps; if (availableBandwidthMbps < contractBandwidth.BandwidthMbps) { throw new AttachmentDomainException($"Insufficient bandwidth remaining. Attachment '{this.Name}' has '{availableBandwidthMbps}' " + "Mbps available."); } contractBandwidthPool = new ContractBandwidthPool(contractBandwidth, trustReceivedCosAndDscp, tenantId); } var vif = new Vif(this.Id, tenantId, role, mtu, vlans, vlanTag.Value, contractBandwidthPool, trustReceivedCosAndDscp); this._vifs.Add(vif); }
/// <summary> /// Delete a vifs which belongs to the attachment /// </summary> /// <returns>An awaitable task</returns> public void DeleteVif(Vif vif) { // Additional logic before deleting a vif this._vifs.Remove(vif); }