/** * If any endpoint is used in an active File Export, throws an exception * * @param endpoints endpoints being added * @param varrays endpoints belong to * <p>Assumes endpoint formats have been validated. */ public static void checkNotUsedByActiveFileExport(String endpoint, DbClient dbClient) { Network network = NetworkUtil.getEndpointNetwork(endpoint, dbClient); if (network != null) { Set<String> netVArrayIds = network.getConnectedVirtualArrays(); if ((netVArrayIds != null) && (!netVArrayIds.isEmpty())) { Iterator<String> netVArrayIdsIter = netVArrayIds.iterator(); while (netVArrayIdsIter.hasNext()) { String varrayId = netVArrayIdsIter.next(); List<FileShare> fileShares = CustomQueryUtility.queryActiveResourcesByConstraint( dbClient, FileShare.class, AlternateIdConstraint.Factory.getConstraint(FileShare.class, "varray", varrayId)); for (FileShare fileShare : fileShares) { FSExportMap fsExports = fileShare.getFsExports(); if (fsExports != null) { Iterator<FileExport> it = fsExports.values().iterator(); while (it.hasNext()) { FileExport fileExport = it.next(); if (fileExport.getClients().contains(endpoint) || fileExport.getStoragePort().contains(endpoint)) { throw APIException.badRequests.endpointsCannotBeUpdatedActiveExport(endpoint); } } } } } } } }
@Override protected void verifyResults() throws Exception { List<URI> networkURIs = _dbClient.queryByType(Network.class, false); Iterator<Network> networksIter = _dbClient.queryIterativeObjects(Network.class, networkURIs); while (networksIter.hasNext()) { Network network = networksIter.next(); String networkId = network.getId().toString(); StringSet assignedVArrayIds = network.getAssignedVirtualArrays(); if (network.getLabel().equals("NetworkWithVarray")) { Assert.assertTrue( String.format("Network (id=%s) should have an assigned virtual array", networkId), ((assignedVArrayIds != null) && (!assignedVArrayIds.isEmpty()))); int count = 0; for (String assignedVArrayId : assignedVArrayIds) { Assert.assertTrue( "Network has unexpected varray assignment", assignedVArrayId.equals(varrayURI.toString())); count++; } Assert.assertTrue("Network has incorrect varray count", count == 1); } else { Assert.assertTrue( String.format("Network (id=%s) should NOT have an assigned virtual array", networkId), ((assignedVArrayIds == null) || (assignedVArrayIds.isEmpty()))); } } }
/** * Get all the networks belongs to the given network system. * * @param networkSystem * @param allNetworks * @return */ private List<Network> getLocalNetworks(NetworkSystem networkSystem, List<Network> allNetworks) { List<Network> realNetworks = new ArrayList<Network>(); for (Network network : allNetworks) { if (network.getNetworkSystems() != null && network.getNetworkSystems().contains(networkSystem.getId().toString())) { realNetworks.add(network); } } return realNetworks; }
/** * Get the network by the given fabric ID. Return null if not found. * * @param networks * @param fabricId * @return */ private Network getNetworkByNativeId(List<Network> networks, String fabricId) { for (Network network : networks) { if (network != null && network.getNativeId() != null && network.getNativeId().equals(fabricId)) { return network; } } return null; }
/** * Get the connected network systems which are connected by the given transit network. * * @param transitNetwork * @param allNetworks * @return */ private Set<String> getConnectedNetworkSystems(String transitNetwork, List<Network> allNetworks) { Set<String> connectedNetworkSystems = new HashSet<String>(); for (Network network : allNetworks) { if (network.getNetworkSystems() != null && transitNetwork.equals(network.getNativeId())) { for (String networkSystem : network.getNetworkSystems()) { connectedNetworkSystems.add(networkSystem); } } } return connectedNetworkSystems; }
/** * Check if the given network is a remote routed network of the current network system. If it * belongs to a connected network system which is not the current network system, it is a remote * routed network. * * @param network The given network. * @param currentNetworkSystemId The current network system ID. * @param connectedNetworkSystems The connected network systems list. * @return true/false */ private boolean isRemoteRoutedNetwork( Network network, String currentNetworkSystemId, Set<String> connectedNetworkSystems) { if (network.getNetworkSystems() != null) { for (String networkSystem : network.getNetworkSystems()) { if (networkSystem != currentNetworkSystemId && connectedNetworkSystems.contains(networkSystem)) { return true; } } } return false; }
/** * Generate logging output for given network details. * * @param prefix * @param network */ private void dumpRoutedNetworks(String prefix, Network network) { StringBuffer sb = new StringBuffer(); sb.append(prefix + ":"); sb.append("label = " + network.getLabel() + ", "); if (network.getRoutedNetworks() != null) { for (String str : network.getRoutedNetworks()) { sb.append(", routed = " + str); } } else { sb.append(", routed = null"); } _log.info(sb.toString()); }
/** Get all the current networks in the database */ private List<Network> getCurrentTransportZones() throws Exception { List<Network> tzones = new ArrayList<Network>(); List<URI> uriTransportList = dbClient.queryByType(Network.class, true); Iterator<Network> iTZones = dbClient.queryIterativeObjects(Network.class, uriTransportList); while (iTZones.hasNext()) { Network transportZone = iTZones.next(); if (transportZone != null && Transport.FC.toString().equals(transportZone.getTransportType())) { tzones.add(transportZone); } } return tzones; }
/** * Finds the network in the list that has this endpoint. * * @param networks a list of networks * @param endpoint the endpoint * @parame excludeNetwork - exclude this network from result if provided * @return the network that contains the endpoint if found, otherwise null. */ private Network findNetworkForDiscoveredEndPoint( Collection<Network> networks, String endpoint, Network excludeNetwork) { for (Network network : networks) { /* * if excludeNetwork not provided, look for first one. * Otherwise, ignore the provided network */ if (excludeNetwork == null || !network.getId().equals(excludeNetwork.getId())) { if (network.endpointIsDiscovered(endpoint)) { return network; } } } return null; }
private void saveTransportZone(Network network, boolean newTransportZone) throws IOException { if (newTransportZone) { dbClient.createObject(network); _log.info("Added networks {}", network.getLabel()); recordTransportZoneEvent( network, OperationTypeEnum.CREATE_NETWORK.getEvType(true), OperationTypeEnum.CREATE_NETWORK.getDescription()); } else { dbClient.updateAndReindexObject(network); _log.info("Updated transport zone {}", network.getLabel()); recordTransportZoneEvent( network, OperationTypeEnum.UPDATE_NETWORK.getEvType(true), OperationTypeEnum.UPDATE_NETWORK.getDescription()); } }
/** * Get the transit network set if there is, otherwise return empty set. * * @param networkSystem The current discovering network system. * @param allNetworks All the existing networks list. * @return The transit networks list. * @throws Exception The "getFabricIdsMap" may throw exception. */ private Set<String> getTransitNetworks(NetworkSystem networkSystem, List<Network> allNetworks) throws Exception { Map<String, String> networkWwnIdMap = getDevice().getFabricIdsMap(networkSystem); _log.info("getTransitNetworks.networkWwnIdMap = {}", networkWwnIdMap); Set<String> transitNetworks = new HashSet<String>(); for (Entry<String, String> entry : networkWwnIdMap.entrySet()) { String currentNetworkId = entry.getValue(); String currentNetworkWwn = entry.getKey(); Network currentNetwork = getNetworkByNativeId(allNetworks, currentNetworkId); // How to determine it's a transit network: 1. More than one network system have the same // network. if (currentNetwork != null && currentNetwork.getNetworkSystems().size() > 1) { _log.info("Network id={} is a transit VSAN", currentNetworkId); transitNetworks.add(currentNetworkId); } else { _log.info("Network id={} is NOT a transit VSAN", currentNetworkId); } } return transitNetworks; }
/** * Remove the transport zone for a given network system. This typically means to dis-associated it * unless this is the last network system associated with the transport zone. In this case, the * transport zone will be deleted if: * * <ul> * <li>It was discovered * <li>It does not have any user-created ports * <li>It does not have any registered ports * </ul> * * @param tzone * @param uri * @throws IOException */ public List<String> removeNetworkSystemTransportZone(Network tzone, String uri) throws IOException { tzone.removeNetworkSystems(Collections.singletonList(uri)); // dis-associate // list of end points getting deleted ArrayList<String> toRemove = new ArrayList<String>(); if (tzone.getNetworkSystems().isEmpty()) { // if this is the last network system List<String> userCreatedEndPoints = TransportZoneReconciler.getUserCreatedEndPoints(tzone); if (userCreatedEndPoints.isEmpty() && !tzone.assignedToVarray()) { // delete only if not modified by a user _log.info("Removing network {}", tzone.getLabel()); toRemove.addAll(tzone.retrieveEndpoints()); NetworkAssociationHelper.handleEndpointsRemoved(tzone, toRemove, dbClient, _coordinator); dbClient.markForDeletion(tzone); recordTransportZoneEvent( tzone, OperationTypeEnum.DELETE_NETWORK.getEvType(true), OperationTypeEnum.DELETE_NETWORK.getDescription()); } else { _log.info( "Network {} is changed by the user and will " + "not be removed. Discovered end points will be removed.", tzone.getLabel()); for (String pt : tzone.retrieveEndpoints()) { if (!userCreatedEndPoints.contains(pt)) { toRemove.add(pt); } } tzone.removeEndpoints(toRemove); NetworkAssociationHelper.handleEndpointsRemoved(tzone, toRemove, dbClient, _coordinator); _log.info("Discovered endpoints removed {}", toRemove.toArray()); dbClient.persistObject(tzone); recordTransportZoneEvent( tzone, OperationTypeEnum.UPDATE_NETWORK.getEvType(true), OperationTypeEnum.UPDATE_NETWORK.getDescription()); } } else { _log.info("Removing network {} from network system {}", tzone.getLabel(), uri); dbClient.persistObject(tzone); recordTransportZoneEvent( tzone, OperationTypeEnum.UPDATE_NETWORK.getEvType(true), OperationTypeEnum.UPDATE_NETWORK.getDescription()); } return toRemove; }
/** * Get the network the endpoint is associated with if any * * @param endpoint * @param dbClient * @return a reference to a network Assumes endpoint formats have been validated. */ public static Network getEndpointNetwork(String endpoint, DbClient dbClient) { _log.debug("Finding network for endpoint {}", endpoint); URIQueryResultList networkList = new URIQueryResultList(); Iterator<URI> iterator; URI networkUri = null; Network network; dbClient.queryByConstraint( AlternateIdConstraint.Factory.getEndpointNetworkConstraint(endpoint), networkList); iterator = networkList.iterator(); while (iterator.hasNext()) { networkUri = iterator.next(); network = dbClient.queryObject(Network.class, networkUri); if (network != null && network.getInactive() == false) { _log.info("network {} for endpoint {} was found", networkUri, endpoint); return network; } else { _log.info("network {} for endpoint {} was deleted or is inactive", networkUri, endpoint); } } _log.info("network could not be found for endpoint {}", endpoint); return null; }
private void handleEndpointsAdded(Network tzone, Collection<String> endpoints) throws IOException { // find if the endpoints exit in some old transport zone Map<String, Network> transportZoneMap = NetworkAssociationHelper.getNetworksMap(endpoints, dbClient); if (!transportZoneMap.isEmpty()) { _log.info("Added endpoints {} to transport zone {}", endpoints.toArray(), tzone.getLabel()); // before we add the endpoints, they need to be removed from their old transport zones NetworkAssociationHelper.handleRemoveFromOldNetworks( transportZoneMap, tzone, dbClient, _coordinator); } // now, add the the endpoints NetworkAssociationHelper.handleEndpointsAdded(tzone, endpoints, dbClient, _coordinator); }
/** * Update all the networks "routedNetworks" field by adding the routed networks list according to * the given transit network, including both "localNetworks" and "remoteRoutedNetworks". * * @param networkSystem * @param connectedNetworkSystems * @param allNetworks */ private void updateRoutedNetworksForTransitNetwork( NetworkSystem networkSystem, Set<String> connectedNetworkSystems, List<Network> allNetworks) { // 1. Get localNetworks, remoteRoutedNetworks and routedNetworks. With transit network, both the // local // networks and the remote routed networks are routed. List<Network> localNetworks = getLocalNetworks(networkSystem, allNetworks); for (Network network : localNetworks) { dumpRoutedNetworks("localNetwork = ", network); } List<Network> remoteRoutedNetworks = this.getRemoteRoutedNetworks( networkSystem.getId().toString(), connectedNetworkSystems, allNetworks); for (Network network : remoteRoutedNetworks) { dumpRoutedNetworks("remoteRoutedNetworks = ", network); } List<Network> routedNetworks = new ArrayList<Network>(localNetworks); routedNetworks.addAll(remoteRoutedNetworks); for (Network network : routedNetworks) { dumpRoutedNetworks("routedNetworks = ", network); } // 2. Update each local network by setting the routed networks. for (Network currentNetwork : localNetworks) { boolean modified = false; StringSet networkSet = currentNetwork.getRoutedNetworks(); _log.info("NetworkDiscoveryWorker handling routed network, existing: {}", networkSet); if (networkSet == null) { networkSet = new StringSet(); } for (Network routedNetwork : routedNetworks) { if (!networkSet.contains(routedNetwork.getId().toString()) && !routedNetwork.getId().equals(currentNetwork.getId())) { networkSet.add(routedNetwork.getId().toString()); modified = true; } } _log.info("NetworkDiscoveryWorker handling routed network, updated: {}", networkSet); if (modified) { currentNetwork.setRoutedNetworks(networkSet); dumpRoutedNetworks("update network=", currentNetwork); dbClient.updateObject(currentNetwork); } } }
@SuppressWarnings("deprecation") @Override protected void prepareData() throws Exception { // Create a virtual array. VirtualArray varray = new VirtualArray(); varrayURI = URIUtil.createId(VirtualArray.class); varray.setId(varrayURI); _dbClient.createObject(varray); // Create a network and set the virtual array. Network network = new Network(); network.setId(URIUtil.createId(Network.class)); network.setLabel("NetworkWithVarray"); network.setVirtualArray(varrayURI); _dbClient.createObject(network); // Create another network without a virtual array. network = new Network(); network.setId(URIUtil.createId(Network.class)); network.setLabel("NetworkWithoutVArray"); _dbClient.createObject(network); }
/** * Parses the WWN from the network's Native GUID * * @param network the network * @return the network WWN */ public static String getNetworkWwn(Network network) { return parseNetworkWwn(network.getNativeGuid()); }
/** * Given the updated list of end points for one network system, this function will update the * transport zones. Require lock when reconciles vsan in fabrics that are linked through ISL. * Without locking, multiple VSANs could have same native gui id within the same fabric. * * @param networkSystem the network system * @param routedEndpoints IN/OUT parameter to get the routed endpoints map of * Fabric-WWN-to-endpoints-WWN * @throws ControllerException */ private void reconcileTransportZones( NetworkSystem networkSystem, Map<String, Set<String>> routedEndpoints) throws ControllerException { _log.info("reconcileTransportZones for networkSystem {}", networkSystem.getId()); ControllerServiceImpl.Lock lock = ControllerServiceImpl.Lock.getLock(ControllerServiceImpl.DISCOVERY_RECONCILE_TZ); try { _log.debug( "Acquiring lock to reconcile transport zone for networkSystem {}", networkSystem.getId()); lock.acquire(); _log.info( "Acquired lock to reconcile transport zone for networkSystem {}", networkSystem.getId()); // get the network system's connections from the database Iterator<FCEndpoint> iNewEndPoints = getNetworkSystemEndPoints(networkSystem); // get all the transport zones we have in the DB List<Network> oldTransportZones = getCurrentTransportZones(); _log.info("Found {} existing transport zones", oldTransportZones.size()); // get the fabrics that exist on the network system Map<String, String> fabricIdsMap = getDevice().getFabricIdsMap(networkSystem); // get the list of fabrics added, removed, changed TransportZoneReconciler reconciler = new TransportZoneReconciler(); TransportZoneReconciler.Results results = reconciler.reconcile(networkSystem, iNewEndPoints, fabricIdsMap, oldTransportZones); String networkSystemUri = networkSystem.getId().toString(); for (Network tzone : results.getRemoved()) { List<String> removedEps = removeNetworkSystemTransportZone(tzone, networkSystemUri); _log.info( "Removed network {} which removed discovered endpoints {}", tzone.getNativeGuid(), removedEps); } for (Network tzone : results.getAdded()) { handleEndpointsAdded(tzone, tzone.retrieveEndpoints()); saveTransportZone(tzone, true); } for (Network tzone : results.getModified()) { if (results.getRemovedEndPoints().get(tzone) != null) { NetworkAssociationHelper.handleEndpointsRemoved( tzone, results.getRemovedEndPoints().get(tzone), dbClient, _coordinator); } if (results.getAddedEndPoints().get(tzone) != null) { handleEndpointsAdded(tzone, results.getAddedEndPoints().get(tzone)); } saveTransportZone(tzone, false); } // update routed networks for routed and modified networks updateRoutedNetworks(networkSystem, results.getAddedAndModified(), routedEndpoints); } catch (Exception ex) { throw NetworkDeviceControllerException.exceptions.reconcileTransportZonesFailedExc( new Date().toString(), ex); } finally { try { _log.debug( "Releasing reconcile transport zone lock for networkSystem {}", networkSystem.getId()); lock.release(); _log.info( "Released reconcile transport zone lock for networkSystem {}", networkSystem.getId()); } catch (Exception e) { _log.error( "Failed to release Lock while reconcile transport zone for network {} -->{}", networkSystem.getId(), e.getMessage()); } } }
/** * Looks in the topology view for endpoints that accessible by routing * * @param networkSystem the network system being refreshed * @param updatedNetworks the networks that require updating * @param routedEndpoints the routed endpoints map of Fabric-WWN-to-endpoints-WWN * @throws Exception */ private void updateRoutedNetworks( NetworkSystem networkSystem, List<Network> updatedNetworks, Map<String, Set<String>> routedEndpoints) throws Exception { // for each network, get the list of routed ports and locate them in other networks StringSet routedNetworks = null; Network routedNetwork = null; // get the current networks from the database Map<URI, Network> allNetworks = DataObjectUtils.toMap(getCurrentTransportZones()); for (Network network : updatedNetworks) { // if this network has any routed endpoints Set<String> netRoutedEndpoints = routedEndpoints.get(NetworkUtil.getNetworkWwn(network)); if (netRoutedEndpoints == null || netRoutedEndpoints.isEmpty()) { _log.debug("No routed endpoint in network {}", network.getNativeGuid()); network.setRoutedNetworks(null); } else { _log.info( "Found {} routed endpoint in network {}", netRoutedEndpoints, network.getNativeGuid()); routedNetworks = new StringSet(); for (String endpoint : netRoutedEndpoints) { // find the source network of the routed endpoint routedNetwork = findNetworkForDiscoveredEndPoint(allNetworks.values(), endpoint, network); if (routedNetwork != null) { // it is possible we did not discover the source routedNetworks.add(routedNetwork.getId().toString()); } } network.setRoutedNetworks(routedNetworks); } dbClient.updateAndReindexObject(network); _log.info("Updated routed networks for {} to {}", network.getNativeGuid(), routedNetworks); } // clean up transit networks from any one-way associations. // Transit networks will show any endpoints routed thru them // which may cause one-way associations in the routedNetworks. // For example if network A has ep1 and B has ep2 and there is // a routed zone between A and B, the transit network C will // reports ep1 and ep2 but there is not actual routing between // C and A or C and B, so we want to remove these associations. for (URI id : allNetworks.keySet()) { Network net = allNetworks.get(id); boolean updated = false; if (net.getRoutedNetworks() != null) { routedNetworks = new StringSet(net.getRoutedNetworks()); // for each network this network is pointing to for (String strUri : net.getRoutedNetworks()) { // get the opposite network Network opNet = allNetworks.get(URI.create(strUri)); if (opNet != null // it is possible this network is getting removed - the next discovery // cleans up && opNet.getRoutedNetworks() != null // check for null in case the other network routed eps are not yet visible && !opNet .getRoutedNetworks() .contains(net.getId().toString())) { // if the opposite network is not seeing this // one // remove this association because the opposite network is does not have the matching // association routedNetworks.remove(opNet.getId().toString()); updated = true; } } if (updated) { _log.info("Reconciled routed networks for {} to {}", net.getNativeGuid(), routedNetworks); net.setRoutedNetworks(routedNetworks); dbClient.updateAndReindexObject(net); } } } for (Network network : allNetworks.values()) { NetworkAssociationHelper.setNetworkConnectedVirtualArrays(network, false, dbClient); } /* * COP-23266, COP-20698: Fix the problem that ViPR could not create IVR zone between VSANs routed by * transit VSAN(network), the "routedNetwork" field of "Network" data object should be updated based * on the transit network(s) if there is. */ this.updateTransitRoutedNetworks(networkSystem); }