/** * Assign a {@link FloatingIP} from the given {@link FloatingNetwork} to the given {@link Port}. * It will either assign an existing floating IP or it will create and assign a new floating IP. * * @param port the {@link Port} to which a floating IP to be assigned. * @param floatingNetworkUuid the network uuid of the floating network from which a floating IP to * be chosen/created * @return the assigned Floating IP */ private FloatingIP assignFloatingIP(Port port, String floatingNetworkUuid) { // checking whether if there are any available floating IPs in the external network // if there are any we don't need to create a new one ArrayList<FloatingIP> unassignedFloatingIPs = getUnassignedFloatingIPsByNetworkUuid(floatingNetworkUuid); // we should remove all predefined floating IPs from unassigned list // otherwise, these predefined floating IPs can be associated to some other interfaces if (unassignedFloatingIPs != null) { if (log.isDebugEnabled()) { String msg = String.format( "Unassigned floating IPs from the network %s - %s", floatingNetworkUuid, unassignedFloatingIPs.toString()); log.debug(msg); } Iterator<FloatingIP> unassginedFloatingIPsIterator = unassignedFloatingIPs.iterator(); while (unassginedFloatingIPsIterator.hasNext()) { FloatingIP floatingIP = unassginedFloatingIPsIterator.next(); List<String> allPredefinedFloatingIPs = getAllPredefinedFloatingIPs(iaasProvider.getNetworkInterfaces()); if (allPredefinedFloatingIPs != null && !allPredefinedFloatingIPs.isEmpty()) { if (log.isDebugEnabled()) { String msg = String.format( "Predefined floating IPs - %s found in cartridge", allPredefinedFloatingIPs.toString()); log.debug(msg); } Iterator<String> predefinedFloatingIPsIterator = allPredefinedFloatingIPs.iterator(); while (predefinedFloatingIPsIterator.hasNext()) { String floatingIPAddress = predefinedFloatingIPsIterator.next(); if (floatingIP.getFloatingIpAddress() != null && floatingIP.getFloatingIpAddress().equals(floatingIPAddress)) { unassginedFloatingIPsIterator.remove(); if (log.isDebugEnabled()) { String msg = String.format( "Removed predefined floating IP %s from available floating IPs", floatingIPAddress); log.debug(msg); } } } } } } if (unassignedFloatingIPs == null || unassignedFloatingIPs.isEmpty()) { return createAndAssignFloatingIP(port, floatingNetworkUuid); } if (log.isDebugEnabled()) { String msg = String.format( "Available floating IPs from the network %s - %s", floatingNetworkUuid, unassignedFloatingIPs.toString()); log.debug(msg); } // shuffle and get the last for randomness Collections.shuffle(unassignedFloatingIPs); FloatingIP selectedFloatingIP = Iterables.getLast(unassignedFloatingIPs); if (log.isDebugEnabled()) { String msg = String.format( "Floating IP %s is selected among %s from the network %s", selectedFloatingIP.getFloatingIpAddress(), unassignedFloatingIPs.toString(), floatingNetworkUuid); log.debug(msg); } return updateFloatingIP(selectedFloatingIP, port); }
@Override public List<String> associateAddresses(NodeMetadata node) { assertNotNull(node, "Node cannot be null"); if (null == neutronApi || null == portApi || null == floatingIPApi) { buildNeutronApi(); } // internal network uuid to floating networks map, as defined in cartridge definition Map<String, List<FloatingNetwork>> networkUuidToFloatingNetworksMap = getNetworkUuidToFloatingNetworksMap(iaasProvider.getNetworkInterfaces()); // private IP to floating networks map, as defined in cartridge definition Map<String, List<FloatingNetwork>> fixedIPToFloatingNetworksMap = getFixedIPToFloatingNetworksMap(iaasProvider.getNetworkInterfaces()); // list of IPs allocated to this node List<String> associatedFloatingIPs = new ArrayList<String>(); // wait until node gets private IPs while (node.getPrivateAddresses() == null) { CloudControllerUtil.sleep(1000); } // loop through all the fixed IPs of this node // and see whether we need to assign floating IP to each according to the cartridge deployment for (String privateIPOfTheNode : node.getPrivateAddresses()) { Port portOfTheFixedIP = getPortByFixedIP(privateIPOfTheNode); if (null == portOfTheFixedIP) { // we can't assign floating IP if port is null // it can't happen, a fixed/private IP can't live without a port // but doing a null check to be on the safe side if (log.isDebugEnabled()) { String msg = String.format("Port not found for fixed IP %s", privateIPOfTheNode); log.debug(msg); } continue; } // get list of floating networks associated with each network interfaces (refer cartridge // definition) List<FloatingNetwork> floatingNetworks = networkUuidToFloatingNetworksMap.get(portOfTheFixedIP.getNetworkId()); // if no floating networks is defined for a network interface, no need to assign any floating // IPs, skip the current iteration if (null == floatingNetworks || floatingNetworks.isEmpty()) { // since no floating networks found in networkUuidToFloatingNetworksMap, // we will search in fixedIPToFloatingNetworksMap floatingNetworks = fixedIPToFloatingNetworksMap.get(privateIPOfTheNode); if (null == floatingNetworks || floatingNetworks.isEmpty()) { if (log.isDebugEnabled()) { String msg = String.format( "No floating networks defined for the network interface %s", portOfTheFixedIP.getNetworkId()); log.debug(msg); } } continue; } // if floating networks defined for a network interface, assign one floating IP from each // floating network for (FloatingNetwork floatingNetwork : floatingNetworks) { FloatingIP allocatedFloatingIP = null; if (floatingNetwork.getNetworkUuid() != null && !floatingNetwork.getNetworkUuid().isEmpty()) { allocatedFloatingIP = assignFloatingIP(portOfTheFixedIP, floatingNetwork.getNetworkUuid()); } else if (floatingNetwork.getFloatingIP() != null && !floatingNetwork.getFloatingIP().isEmpty()) { allocatedFloatingIP = assignPredefinedFloatingIP(portOfTheFixedIP, floatingNetwork.getFloatingIP()); } else { String msg = String.format( "Neither floating network uuid or floating IP defined for the floating network %s", floatingNetwork.getName()); log.error(msg); throw new CloudControllerException(msg); } String allocatedFloatingIPNullMsg = String.format( "Error occured while assigning floating IP. " + "Please check whether the floating network %s can be reached from the fixed IP range", floatingNetwork.getNetworkUuid()); assertNotNull(allocatedFloatingIP, allocatedFloatingIPNullMsg); String allocatedFloatingIPAddressNullOrEmptyMsg = String.format( "Error occured while assigning floating IP. " + "Please check whether the floating network %s can be reached from the fixed IP range", floatingNetwork.getNetworkUuid()); assertNotNullAndNotEmpty( allocatedFloatingIP.getFloatingIpAddress(), allocatedFloatingIPAddressNullOrEmptyMsg); associatedFloatingIPs.add(allocatedFloatingIP.getFloatingIpAddress()); } } return associatedFloatingIPs; }
public void buildTemplate() { IaasProvider iaasInfo = getIaasProvider(); if (iaasInfo.getComputeService() == null) { String msg = "Compute service is null for IaaS provider: " + iaasInfo.getName(); log.fatal(msg); throw new CloudControllerException(msg); } TemplateBuilder templateBuilder = iaasInfo.getComputeService().templateBuilder(); // set image id specified templateBuilder.imageId(iaasInfo.getImage()); if (iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE) != null) { Set<? extends Location> locations = iaasInfo.getComputeService().listAssignableLocations(); for (Location location : locations) { if (location.getScope().toString().equalsIgnoreCase(CloudControllerConstants.ZONE_ELEMENT) && location .getId() .equals(iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE))) { templateBuilder.locationId(location.getId()); log.info( "ZONE has been set as " + iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE) + " with id: " + location.getId()); break; } } } if (iaasInfo.getProperty(CloudControllerConstants.INSTANCE_TYPE) != null) { // set instance type eg: m1.large templateBuilder.hardwareId(iaasInfo.getProperty(CloudControllerConstants.INSTANCE_TYPE)); } // build the Template Template template = templateBuilder.build(); if (iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE) != null) { if (!template .getLocation() .getId() .equals(iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE))) { log.warn( "couldn't find assignable ZONE of id :" + iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE) + " in the IaaS. " + "Hence using the default location as " + template.getLocation().getScope().toString() + " with the id " + template.getLocation().getId()); } } // if you wish to auto assign IPs, instance spawning call should be // blocking, but if you // wish to assign IPs manually, it can be non-blocking. // is auto-assign-ip mode or manual-assign-ip mode? boolean blockUntilRunning = Boolean.parseBoolean(iaasInfo.getProperty(CloudControllerConstants.AUTO_ASSIGN_IP)); template.getOptions().as(TemplateOptions.class).blockUntilRunning(blockUntilRunning); // this is required in order to avoid creation of additional security // groups by jclouds. template.getOptions().as(TemplateOptions.class).inboundPorts(); // set EC2 specific options if (iaasInfo.getProperty(CloudControllerConstants.ASSOCIATE_PUBLIC_IP_ADDRESS) != null) { boolean associatePublicIp = Boolean.parseBoolean( iaasInfo.getProperty(CloudControllerConstants.ASSOCIATE_PUBLIC_IP_ADDRESS)); if (associatePublicIp) { template.getOptions().as(AWSEC2TemplateOptions.class).associatePublicIpAddress(); } } if (iaasInfo.getProperty(CloudControllerConstants.SUBNET_ID) != null) { template .getOptions() .as(AWSEC2TemplateOptions.class) .subnetId(iaasInfo.getProperty(CloudControllerConstants.SUBNET_ID)); } if (iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE) != null) { template .getOptions() .as(AWSEC2TemplateOptions.class) .placementGroup(iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE)); } // security group names if (iaasInfo.getProperty(CloudControllerConstants.SECURITY_GROUPS) != null) { template .getOptions() .as(AWSEC2TemplateOptions.class) .securityGroups( iaasInfo .getProperty(CloudControllerConstants.SECURITY_GROUPS) .split(CloudControllerConstants.ENTRY_SEPARATOR)); } // ability to define tags if (iaasInfo.getProperty(CloudControllerConstants.TAGS) != null) { template .getOptions() .as(AWSEC2TemplateOptions.class) .tags( Arrays.asList( iaasInfo .getProperty(CloudControllerConstants.TAGS) .split(CloudControllerConstants.ENTRY_SEPARATOR))); } // ability to define tags with Key-value pairs Map<String, String> keyValuePairTagsMap = new HashMap<String, String>(); for (String propertyKey : iaasInfo.getProperties().keySet()) { if (propertyKey.startsWith(CloudControllerConstants.TAGS_AS_KEY_VALUE_PAIRS_PREFIX)) { keyValuePairTagsMap.put( propertyKey.substring(CloudControllerConstants.TAGS_AS_KEY_VALUE_PAIRS_PREFIX.length()), iaasInfo.getProperties().get(propertyKey)); template.getOptions().as(AWSEC2TemplateOptions.class).userMetadata(keyValuePairTagsMap); } } if (iaasInfo.getProperty(CloudControllerConstants.SECURITY_GROUP_IDS) != null) { template .getOptions() .as(AWSEC2TemplateOptions.class) .securityGroupIds( iaasInfo .getProperty(CloudControllerConstants.SECURITY_GROUP_IDS) .split(CloudControllerConstants.ENTRY_SEPARATOR)); } if (iaasInfo.getProperty(CloudControllerConstants.KEY_PAIR) != null) { template .getOptions() .as(AWSEC2TemplateOptions.class) .keyPair(iaasInfo.getProperty(CloudControllerConstants.KEY_PAIR)); } if (iaasInfo.getNetworkInterfaces() != null) { List<String> networks = new ArrayList<String>(iaasInfo.getNetworkInterfaces().length); for (NetworkInterface ni : iaasInfo.getNetworkInterfaces()) { networks.add(ni.getNetworkUuid()); } template.getOptions().as(AWSEC2TemplateOptions.class).networks(networks); } // set Template iaasInfo.setTemplate(template); }