public static Allocation start(final VmInstance vm) { BootableSet bootSet = Emis.recreateBootableSet(vm); return new Allocation( vm.getReservationId(), vm.getInstanceId(), vm.getInstanceUuid(), vm.getUserData(), vm.getExpiration(), vm.lookupPartition(), vm.getKeyPair(), bootSet, vm.getVmType(), vm.getNetworkGroups(), vm.isUsePrivateAddressing(), vm.getMonitoring(), vm.getClientToken(), vm.getIamInstanceProfileArn(), vm.getIamInstanceProfileId(), vm.getIamRoleArn()); }
public class NetworkInfoBroadcaster { private static final Logger logger = Logger.getLogger(NetworkInfoBroadcaster.class); private static final AtomicLong lastBroadcastTime = new AtomicLong(0L); private static final Lock lastBroadcastTimeLock = new ReentrantLock(); private static final Semaphore activeBroadcastSemaphore = new Semaphore(1); private static final EntityCache<VmInstance, NetworkInfoBroadcasts.VmInstanceNetworkView> instanceCache = new EntityCache<>( VmInstance.named(null), Restrictions.not(VmInstance.criterion(TORNDOWN.array())), Sets.newHashSet("networkGroups"), Sets.newHashSet("bootRecord.machineImage", "bootRecord.vmType"), TypeMappers.lookup(VmInstance.class, VmInstanceNetworkView.class)); private static final EntityCache<NetworkGroup, NetworkGroupNetworkView> securityGroupCache = new EntityCache<>( NetworkGroup.withNaturalId(null), TypeMappers.lookup(NetworkGroup.class, NetworkGroupNetworkView.class)); private static final EntityCache<Vpc, VpcNetworkView> vpcCache = new EntityCache<>( Vpc.exampleWithOwner(null), TypeMappers.lookup(Vpc.class, VpcNetworkView.class)); private static final EntityCache<Subnet, SubnetNetworkView> subnetCache = new EntityCache<>( Subnet.exampleWithOwner(null), TypeMappers.lookup(Subnet.class, SubnetNetworkView.class)); private static final EntityCache<DhcpOptionSet, DhcpOptionSetNetworkView> dhcpOptionsCache = new EntityCache<>( DhcpOptionSet.exampleWithOwner(null), TypeMappers.lookup(DhcpOptionSet.class, DhcpOptionSetNetworkView.class)); private static final EntityCache<NetworkAcl, NetworkAclNetworkView> networkAclCache = new EntityCache<>( NetworkAcl.exampleWithOwner(null), TypeMappers.lookup(NetworkAcl.class, NetworkAclNetworkView.class)); private static final EntityCache<RouteTable, RouteTableNetworkView> routeTableCache = new EntityCache<>( RouteTable.exampleWithOwner(null), TypeMappers.lookup(RouteTable.class, RouteTableNetworkView.class)); private static final EntityCache<InternetGateway, InternetGatewayNetworkView> internetGatewayCache = new EntityCache<>( InternetGateway.exampleWithOwner(null), TypeMappers.lookup(InternetGateway.class, InternetGatewayNetworkView.class)); private static final EntityCache<NetworkInterface, NetworkInterfaceNetworkView> networkInterfaceCache = new EntityCache<>( NetworkInterface.exampleWithOwner(null), TypeMappers.lookup(NetworkInterface.class, NetworkInterfaceNetworkView.class)); private static final EntityCache<NatGateway, NatGatewayNetworkView> natGatewayCache = new EntityCache<>( NatGateway.exampleWithOwner(null), TypeMappers.lookup(NatGateway.class, NatGatewayNetworkView.class)); private static final VpcRouteStateInvalidator vpcRouteStateInvalidator = new EventFiringVpcRouteStateInvalidator(); private static NetworkInfoSource cacheSource() { final Supplier<Iterable<VmInstanceNetworkView>> instanceSupplier = Suppliers.memoize(instanceCache); final Supplier<Iterable<NetworkGroupNetworkView>> securityGroupSupplier = Suppliers.memoize(securityGroupCache); final Supplier<Iterable<VpcNetworkView>> vpcSupplier = Suppliers.memoize(vpcCache); final Supplier<Iterable<SubnetNetworkView>> subnetSupplier = Suppliers.memoize(subnetCache); final Supplier<Iterable<DhcpOptionSetNetworkView>> dhcpOptionsSupplier = Suppliers.memoize(dhcpOptionsCache); final Supplier<Iterable<NetworkAclNetworkView>> networkAclSupplier = Suppliers.memoize(networkAclCache); final Supplier<Iterable<RouteTableNetworkView>> routeTableSupplier = Suppliers.memoize(routeTableCache); final Supplier<Iterable<InternetGatewayNetworkView>> internetGatewaySupplier = Suppliers.memoize(internetGatewayCache); final Supplier<Iterable<NetworkInterfaceNetworkView>> networkInterfaceSupplier = Suppliers.memoize(networkInterfaceCache); final Supplier<Iterable<NatGatewayNetworkView>> natGatewaySupplier = Suppliers.memoize(natGatewayCache); return new NetworkInfoSource() { @Override public Iterable<VmInstanceNetworkView> getInstances() { return instanceSupplier.get(); } @Override public Iterable<NetworkGroupNetworkView> getSecurityGroups() { return securityGroupSupplier.get(); } @Override public Iterable<VpcNetworkView> getVpcs() { return vpcSupplier.get(); } @Override public Iterable<SubnetNetworkView> getSubnets() { return subnetSupplier.get(); } @Override public Iterable<DhcpOptionSetNetworkView> getDhcpOptionSets() { return dhcpOptionsSupplier.get(); } @Override public Iterable<NetworkAclNetworkView> getNetworkAcls() { return networkAclSupplier.get(); } @Override public Iterable<RouteTableNetworkView> getRouteTables() { return routeTableSupplier.get(); } @Override public Iterable<InternetGatewayNetworkView> getInternetGateways() { return internetGatewaySupplier.get(); } @Override public Iterable<NetworkInterfaceNetworkView> getNetworkInterfaces() { return networkInterfaceSupplier.get(); } @Override public Iterable<NatGatewayNetworkView> getNatGateways() { return natGatewaySupplier.get(); } @Override public Map<String, Iterable<? extends VersionedNetworkView>> getView() { return ImmutableMap.<String, Iterable<? extends VersionedNetworkView>>builder() .put("instance", getInstances()) .put("security-group", getSecurityGroups()) .put("vpc", getVpcs()) .put("subnet", getSubnets()) .put("dhcp-option-set", getDhcpOptionSets()) .put("network-acl", getNetworkAcls()) .put("route-table", getRouteTables()) .put("internet-gateway", getInternetGateways()) .put("network-interface", getNetworkInterfaces()) .put("nat-gateway", getNatGateways()) .build(); } }; } public static void requestNetworkInfoBroadcast() { final long requestedTime = System.currentTimeMillis(); final Callable<Void> broadcastRequest = new Callable<Void>() { @Override public Void call() throws Exception { boolean shouldBroadcast = false; boolean shouldRetryWithDelay = false; try (final LockResource lock = LockResource.lock(lastBroadcastTimeLock)) { final long currentTime = System.currentTimeMillis(); final long lastBroadcast = lastBroadcastTime.get(); if (requestedTime >= lastBroadcast && lastBroadcast + TimeUnit.SECONDS.toMillis(NetworkGroups.MIN_BROADCAST_INTERVAL) < currentTime && activeBroadcastSemaphore.availablePermits() > 0) { if (lastBroadcastTime.compareAndSet(lastBroadcast, currentTime)) { shouldBroadcast = true; } else { // re-evaluate broadcastTask(this); } } else if (requestedTime >= lastBroadcastTime.get()) { shouldRetryWithDelay = true; } } if (shouldBroadcast) { try { broadcastNetworkInfo(); } catch (Exception e) { logger.error("Error broadcasting network information", e); } } else if (shouldRetryWithDelay) { Thread.sleep(100); // pause and re-evaluate to allow for min time between broadcasts broadcastTask(this); } return null; } }; broadcastTask(broadcastRequest); } private static void broadcastTask(Callable<Void> task) { Threads.enqueue(Eucalyptus.class, NetworkInfoBroadcaster.class, 5, task); } @SuppressWarnings("UnnecessaryQualifiedReference") static void broadcastNetworkInfo() { try (final SemaphoreResource semaphore = SemaphoreResource.acquire(activeBroadcastSemaphore)) { // populate with info directly from configuration final Optional<NetworkConfiguration> networkConfiguration = NetworkConfigurations.getNetworkConfiguration(); final List<com.eucalyptus.cluster.Cluster> clusters = Clusters.getInstance().listValues(); final NetworkInfoSource source = cacheSource(); final Set<String> dirtyPublicAddresses = PublicAddresses.dirtySnapshot(); final Set<RouteKey> invalidStateRoutes = Sets.newHashSetWithExpectedSize(50); final int sourceFingerprint = fingerprint(source, clusters, dirtyPublicAddresses, NetworkGroups.NETWORK_CONFIGURATION); final NetworkInfo info = NetworkInfoBroadcasts.buildNetworkConfiguration( networkConfiguration, source, Suppliers.ofInstance(clusters), new Supplier<String>() { @Override public String get() { return Topology.lookup(Eucalyptus.class).getInetAddress().getHostAddress(); } }, new Function<List<String>, List<String>>() { @Nullable @Override public List<String> apply(final List<String> defaultServers) { return NetworkConfigurations.loadSystemNameservers(defaultServers); } }, dirtyPublicAddresses, invalidStateRoutes); info.setVersion( BaseEncoding.base16().lowerCase().encode(Ints.toByteArray(sourceFingerprint))); if (!invalidStateRoutes.isEmpty()) { vpcRouteStateInvalidator.accept(invalidStateRoutes); } Applicators.apply(clusters, info); } catch (ApplicatorException e) { logger.error("Error during network broadcast", e); } } private static int fingerprint( final NetworkInfoSource source, final List<com.eucalyptus.cluster.Cluster> clusters, final Set<String> dirtyPublicAddresses, final String networkConfiguration) { final HashFunction hashFunction = goodFastHash(32); final Hasher hasher = hashFunction.newHasher(); final Funnel<VersionedNetworkView> versionedItemFunnel = new Funnel<VersionedNetworkView>() { @Override public void funnel(final VersionedNetworkView o, final PrimitiveSink primitiveSink) { primitiveSink.putString(o.getId(), StandardCharsets.UTF_8); primitiveSink.putChar('='); primitiveSink.putInt(o.getVersion()); } }; for (final Map.Entry<String, Iterable<? extends VersionedNetworkView>> entry : source.getView().entrySet()) { hasher.putString(entry.getKey(), StandardCharsets.UTF_8); for (final VersionedNetworkView item : entry.getValue()) { hasher.putObject(item, versionedItemFunnel); } } hasher.putString( Joiner.on(',').join(Sets.newTreeSet(Iterables.transform(clusters, HasName.GET_NAME))), StandardCharsets.UTF_8); hasher.putString( Joiner.on(',').join(Sets.newTreeSet(dirtyPublicAddresses)), StandardCharsets.UTF_8); hasher.putInt(networkConfiguration.hashCode()); return hasher.hash().asInt(); } public static class NetworkInfoBroadcasterEventListener implements EventListener<ClockTick> { private final int intervalTicks = 3; private volatile int counter = 0; public static void register() { Listeners.register(ClockTick.class, new NetworkInfoBroadcasterEventListener()); } @SuppressWarnings("UnnecessaryQualifiedReference") @Override public void fireEvent(final ClockTick event) { if (counter++ % intervalTicks == 0 && Topology.isEnabledLocally(Eucalyptus.class) && Hosts.isCoordinator() && Bootstrap.isOperational() && !Databases.isVolatile()) { requestNetworkInfoBroadcast(); } } } }