/*************************************************************************
* Copyright 2009-2016 Eucalyptus Systems, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
*
* Please contact Eucalyptus Systems, Inc., 6755 Hollister Ave., Goleta
* CA 93117, USA or visit http://www.eucalyptus.com/licenses/ if you need
* additional information or have any questions.
************************************************************************/
package com.eucalyptus.objectstorage;
import java.net.InetAddress;
import java.util.Collections;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.stream.Collectors;
import org.xbill.DNS.Name;
import org.xbill.DNS.Record;
import com.eucalyptus.bootstrap.Bootstrap;
import com.eucalyptus.bootstrap.Hosts;
import com.eucalyptus.component.ServiceConfiguration;
import com.eucalyptus.component.Topology;
import com.eucalyptus.objectstorage.util.OSGUtil;
import com.eucalyptus.util.Cidr;
import com.eucalyptus.util.EucalyptusCloudException;
import com.eucalyptus.util.Internets;
import com.eucalyptus.util.dns.DomainNameRecords;
import com.eucalyptus.util.dns.DomainNames;
import com.eucalyptus.util.dns.DnsResolvers.DnsRequest;
import com.eucalyptus.util.dns.DnsResolvers.DnsResolver;
import com.eucalyptus.util.dns.DnsResolvers.DnsResponse;
import com.eucalyptus.util.dns.DnsResolvers.RequestType;
import com.google.common.collect.Lists;
@SuppressWarnings( "unused" )
public class ObjectStorageBucketResolver extends DnsResolver {
@Override
public boolean checkAccepts(DnsRequest request) {
if ( !Bootstrap.isOperational( ) ) {
return false;
}
final Record query = request.getQuery( );
return OSGUtil.isBucketName( query.getName( ), false );
}
@Override
public DnsResponse lookupRecords(DnsRequest request) {
final Record query = request.getQuery( );
final Name name = query.getName( );
if ( !DomainNames.isSystemSubdomain( query.getName( ) ) ) {
throw new NoSuchElementException( "Failed to lookup name: " + name );
}
if ( !RequestType.A.apply( query ) ) {
return DnsResponse.forName( query.getName( ) ).answer( Collections.emptyList( ) );
}
try {
final List<InetAddress> osgIps = ObjectStorageAddresses.getObjectStorageAddress( );
final List<Record> records = Lists.newArrayList( );
records.addAll( osgIps.stream( )
.map( osgIp -> DomainNameRecords.addressRecord( name, maphost( request.getLocalAddress( ), osgIp ) ) )
.collect( Collectors.toList( ) ) );
return DnsResponse.forName( query.getName( ) ).answer( records );
} catch( final Exception ex ) {
return DnsResponse.forName( query.getName( ) ).nxdomain( );
}
}
private static class ObjectStorageAddresses {
static List<InetAddress> getObjectStorageAddress( ) throws EucalyptusCloudException {
if ( Topology.isEnabled( ObjectStorage.class ) ) {
final Iterable<ServiceConfiguration> osgs = Topology.lookupMany( ObjectStorage.class );
final List<InetAddress> addresses = Lists.newArrayList( );
for ( final ServiceConfiguration configuration : osgs ) {
addresses.add( configuration.getInetAddress( ) );
}
Collections.shuffle( addresses );
return addresses;
} else {
throw new EucalyptusCloudException("ObjectStorage not ENABLED");
}
}
}
private static InetAddress maphost( final InetAddress listenerAddress,
final InetAddress hostAddress ) {
return Hosts.maphost(
hostAddress,
listenerAddress,
Internets.getInterfaceCidr( listenerAddress ).or( Cidr.of( 0, 0 ) ) );
}
}