package denominator; import java.util.Collection; import java.util.Map; import java.util.Set; import denominator.model.ResourceRecordSet; /** * Metadata about a provider of DNS services. * * <br> <br> <b>Writing a Provider</b><br> * * The current implementation of {@link Denominator#create(Provider, Object...)} expects all {@code * Provider} implementations to expose a static inner class named {@code Module}. <br> The inner * class is expected to have a {@link dagger.Module} annotation such as below: * * <pre> * public class MockProvider extends BasicProvider { * * @dagger.Module(injects = DNSApiManager.class, complete = false, includes = * NothingToClose.class) * public static final class Module { * </pre> * * Look at {@link denominator.mock.MockProvider.Module} for an example of a valid provider module. * * <br> <br> <b>Expected Use</b><br> Provider instances are bound in {@link javax.inject.Singleton} * scope. However, results of all methods are permitted to change at runtime. For example, a change * to the value returned by {@link #url()} should affect the remote connection to the DNS provider. */ public interface Provider { /** * configuration key associated with this {@link DNSApi}. For example, {@code hopper}. */ String name(); /** * The base API URL of the DNS Provider. Typically, a http url, such as {@code https://api/v2}. * For in-memory providers, we expect the scheme to be {@code mem}. For example, {@code * mem://mock}. Encoding credentials in the URL is neither expected nor supported. */ String url(); /** * The set of basic {@link ResourceRecordSet#type() record types} that are supported by {@link * ResourceRecordSetApi} commands. <br> For example: * * <pre> * ["A", "AAAA", "CNAME", "HINFO", "MX", "PTR", "RP", "SRV", "TXT", "NAPTR"] * </pre> */ Set<String> basicRecordTypes(); /** * Maps a profile value to a collection of supported record types. If empty, the provider does not * support advanced records. * * <p/> For example: * * <pre> * { "geo" : ["A", "AAAA", "CNAME", "HINFO", "MX", "PTR", "RP", "SRV", "TXT", "NAPTR"], * "weighted" : ["A", "AAAA", "CNAME"] } * </pre> * * <p/> Well known record types are in the {@code denominator.model.profile} package. */ Map<String, Collection<String>> profileToRecordTypes(); /** * Duplicate zones can exist with the same name. */ boolean supportsDuplicateZoneNames(); /** * Description of the credential parameters needed for this provider by type. Multiple entries are * present when the provider supports multiple credential types, and the order of these entries * suggests priority. No entries suggest this provider does not require credentials. Values are an * ordered list of labels that describe the credential parts required to authenticate, for example * {@code ["username", "password"]}. * * <br> <br> <b>Credential Type</b><br> * * The credential type keys intend to easily disambiguate cases where multiple means of * authentication exist, or where authentication means share the same number of parts. For * example, in Amazon, the keySet might be {@code ["accessKey", "stsSession"]}, where default is * contains the access and secret key, and {@code stsSession} adds a token. In an {@code * OpenStack} provider the keySet might be {@code ["password", "apiAccessKey"]}, which * disambiguates the case where both {@code password} and {@code apiAccessKey} authentication * require the same number of parts. * * <br> <br> <b>Credential Labels</b><br> * * Values are an ordered list of labels that describe the credential parts required to * authenticate, for example {@code ["username", "password"]}. This information is targeted at * users who may otherwise be confused what secrets are necessary for this provider. * * <br> <br> <b>Example</b><br> * * Given an entry with values: {@code ["accessKey", "secretKey"]}, we know the order of the * parameters in a {@code Collection}-based Credentials object, or the keys needed for a {@code * Map}-based one. * * <pre> * return new BasicAWSCredentials(creds.get(0).toString(), creds.get(1).toString()); * // or if map-backed * return new BasicAWSCredentials(creds.get("accessKey").toString(), * creds.get("secretKey").toString()); * </pre> * * <br> <br> <b>Formatting</b><br> * * Both the keys and the values of this map are in {@code lowerCamel} case. * * * <br> <br> <b>Implementation Expectations</b><br> * * The implementing provider should throw an {@link IllegalArgumentException} if it is ever * supplied with an incorrect count of credential parts corresponding to this. The preferred * mechanism to access credentials in a way that validates parameters is to use {@code * Provider<Credentials>} bound by {@link CredentialsConfiguration}. * * @return credential types to the labels of each part required. An empty multimap suggests the * provider doesn't authenticate. */ Map<String, Collection<String>> credentialTypeToParameterNames(); }