Skip to content

Commit

Permalink
Add basic authentication to Pinot connector
Browse files Browse the repository at this point in the history
  • Loading branch information
ddcprg authored and ebyhr committed Jan 19, 2022
1 parent 5e37327 commit 830ac66
Show file tree
Hide file tree
Showing 28 changed files with 888 additions and 27 deletions.
17 changes: 17 additions & 0 deletions docs/src/main/sphinx/connector/pinot.rst
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,25 @@ Property Name Required Description
number of requests made to Pinot. This is useful for smaller Pinot clusters.
``pinot.request-timeout`` No The timeout for Pinot requests. Increasing this can reduce timeouts if DNS
resolution is slow.
``pinot.controller.authentication.type`` No Pinot authentication method for controller requests. Allowed values are
``NONE`` and ``PASSWORD`` - defaults to ``NONE`` which is no authentication.
``pinot.controller.authentication.user`` No Controller username for basic authentication method.
``pinot.controller.authentication.password`` No Controller password for basic authentication method.
``pinot.broker.authentication.type`` No Pinot authentication method for broker requests. Allowed values are
``NONE`` and ``PASSWORD`` - defaults to ``NONE`` which is no
authentication.
``pinot.broker.authentication.user`` No Broker username for basic authentication method.
``pinot.broker.authentication.password`` No Broker password for basic authentication method.
============================================= ========== ==============================================================================

If ``pinot.controller.authentication.type`` is set to ``PASSWORD`` then both ``pinot.controller.authentication.user`` and
``pinot.controller.authentication.password`` are required.

If ``pinot.broker.authentication.type`` is set to ``PASSWORD`` then both ``pinot.broker.authentication.user`` and
``pinot.broker.authentication.password`` are required.

You can use :doc:`secrets </security/secrets>` to avoid actual values in the catalog properties files.

Querying Pinot tables
---------------------

Expand Down
12 changes: 12 additions & 0 deletions plugin/trino-pinot/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,18 @@
<artifactId>guice</artifactId>
</dependency>

<!-- Used for basic authentication only -->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<exclusions>
<exclusion>
<groupId>org.codehaus.mojo</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>

<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import io.airlift.bootstrap.Bootstrap;
import io.airlift.json.JsonModule;
import io.trino.plugin.base.TypeDeserializerModule;
import io.trino.plugin.pinot.auth.PinotAuthenticationModule;
import io.trino.spi.connector.Connector;
import io.trino.spi.connector.ConnectorContext;
import io.trino.spi.connector.ConnectorFactory;
Expand Down Expand Up @@ -62,7 +63,8 @@ public Connector create(String catalogName, Map<String, String> config, Connecto
.add(new JsonModule())
.add(new MBeanModule())
.add(new TypeDeserializerModule(context.getTypeManager()))
.add(new PinotModule(catalogName, context.getNodeManager()));
.add(new PinotModule(catalogName, context.getNodeManager()))
.add(new PinotAuthenticationModule());

extension.ifPresent(modulesBuilder::add);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.trino.plugin.pinot.auth;

import com.google.inject.Binder;
import com.google.inject.Module;
import com.google.inject.Provides;
import io.airlift.configuration.AbstractConfigurationAwareModule;
import io.trino.plugin.pinot.auth.none.PinotEmptyAuthenticationProvider;
import io.trino.plugin.pinot.auth.password.PinotPasswordAuthenticationProvider;
import io.trino.plugin.pinot.auth.password.inline.PinotPasswordBrokerAuthenticationConfig;
import io.trino.plugin.pinot.auth.password.inline.PinotPasswordControllerAuthenticationConfig;

import javax.inject.Singleton;

import static io.airlift.configuration.ConditionalModule.conditionalModule;
import static io.airlift.configuration.ConfigBinder.configBinder;
import static io.trino.plugin.pinot.auth.PinotAuthenticationType.NONE;
import static io.trino.plugin.pinot.auth.PinotAuthenticationType.PASSWORD;

public class PinotAuthenticationModule
extends AbstractConfigurationAwareModule
{
@Override
protected void setup(Binder binder)
{
bindAuthenticationProviderModule(
NONE,
new PinotNoneControllerAuthenticationProviderModule(),
new PinotNoneBrokerAuthenticationProviderModule());
bindAuthenticationProviderModule(
PASSWORD,
new PinotPasswordControllerAuthenticationProviderModule(),
new PinotPasswordBrokerAuthenticationProviderModule());
}

private void bindAuthenticationProviderModule(PinotAuthenticationType authType, Module controllerModule, Module brokerModule)
{
install(conditionalModule(
PinotAuthenticationTypeConfig.class,
config -> authType == config.getControllerAuthenticationType(),
controllerModule));
install(conditionalModule(
PinotAuthenticationTypeConfig.class,
config -> authType == config.getBrokerAuthenticationType(),
brokerModule));
}

private static class PinotNoneControllerAuthenticationProviderModule
implements Module
{
@Override
public void configure(Binder binder)
{
}

@Provides
@Singleton
public PinotControllerAuthenticationProvider getAuthenticationProvider()
{
return PinotControllerAuthenticationProvider.create(PinotEmptyAuthenticationProvider.instance());
}
}

private static class PinotNoneBrokerAuthenticationProviderModule
implements Module
{
@Override
public void configure(Binder binder)
{
}

@Provides
@Singleton
public PinotBrokerAuthenticationProvider getAuthenticationProvider()
{
return PinotBrokerAuthenticationProvider.create(PinotEmptyAuthenticationProvider.instance());
}
}

private static class PinotPasswordControllerAuthenticationProviderModule
implements Module
{
@Override
public void configure(Binder binder)
{
configBinder(binder).bindConfig(PinotPasswordControllerAuthenticationConfig.class);
}

@Provides
@Singleton
public PinotControllerAuthenticationProvider getAuthenticationProvider(
PinotPasswordControllerAuthenticationConfig config)
{
return PinotControllerAuthenticationProvider.create(new PinotPasswordAuthenticationProvider(config.getUser(), config.getPassword()));
}
}

private static class PinotPasswordBrokerAuthenticationProviderModule
implements Module
{
@Override
public void configure(Binder binder)
{
configBinder(binder).bindConfig(PinotPasswordBrokerAuthenticationConfig.class);
}

@Provides
@Singleton
public PinotBrokerAuthenticationProvider getAuthenticationProvider(
PinotPasswordBrokerAuthenticationConfig config)
{
return PinotBrokerAuthenticationProvider.create(new PinotPasswordAuthenticationProvider(config.getUser(), config.getPassword()));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.trino.plugin.pinot.auth;

import java.util.Optional;

public interface PinotAuthenticationProvider
{
Optional<String> getAuthenticationToken();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.trino.plugin.pinot.auth;

public enum PinotAuthenticationType {
NONE,
PASSWORD,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.trino.plugin.pinot.auth;

import io.airlift.configuration.Config;

import javax.validation.constraints.NotNull;

public class PinotAuthenticationTypeConfig
{
private PinotAuthenticationType controllerAuthenticationType = PinotAuthenticationType.NONE;
private PinotAuthenticationType brokerAuthenticationType = PinotAuthenticationType.NONE;

@NotNull
public PinotAuthenticationType getControllerAuthenticationType()
{
return controllerAuthenticationType;
}

@Config("pinot.controller.authentication.type")
public PinotAuthenticationTypeConfig setControllerAuthenticationType(PinotAuthenticationType controllerAuthenticationType)
{
this.controllerAuthenticationType = controllerAuthenticationType;
return this;
}

@NotNull
public PinotAuthenticationType getBrokerAuthenticationType()
{
return brokerAuthenticationType;
}

@Config("pinot.broker.authentication.type")
public PinotAuthenticationTypeConfig setBrokerAuthenticationType(PinotAuthenticationType brokerAuthenticationType)
{
this.brokerAuthenticationType = brokerAuthenticationType;
return this;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.trino.plugin.pinot.auth;

import java.util.Optional;

import static java.util.Objects.requireNonNull;

public class PinotBrokerAuthenticationProvider
implements PinotAuthenticationProvider
{
public static PinotBrokerAuthenticationProvider create(PinotAuthenticationProvider delegate)
{
return new PinotBrokerAuthenticationProvider(delegate);
}

private final PinotAuthenticationProvider delegate;

private PinotBrokerAuthenticationProvider(PinotAuthenticationProvider delegate)
{
this.delegate = requireNonNull(delegate, "Delegate broker authentication provider is required");
}

@Override
public Optional<String> getAuthenticationToken()
{
return delegate.getAuthenticationToken();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.trino.plugin.pinot.auth;

import java.util.Optional;

import static java.util.Objects.requireNonNull;

public class PinotControllerAuthenticationProvider
implements PinotAuthenticationProvider
{
public static PinotControllerAuthenticationProvider create(PinotAuthenticationProvider delegate)
{
return new PinotControllerAuthenticationProvider(delegate);
}

private final PinotAuthenticationProvider delegate;

private PinotControllerAuthenticationProvider(PinotAuthenticationProvider delegate)
{
this.delegate = requireNonNull(delegate, "Delegate controller authentication provider is required");
}

@Override
public Optional<String> getAuthenticationToken()
{
return delegate.getAuthenticationToken();
}
}
Loading

0 comments on commit 830ac66

Please sign in to comment.