Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update approach to kafka security for clients #17527

Merged
merged 27 commits into from
Apr 5, 2024

Conversation

travisdowns
Copy link
Member

@travisdowns travisdowns commented Apr 1, 2024

The primary thrust of this change is to consolidate the way our "client wrappers" (i.e., the python code that wraps a Kafka client) get their security credentials to authenticate to the Kafka endpoint. This change only changes ducktape test framework and test code, and does not touch Redpanda itself.

Specifically we want to:

  • Use a strongly typed class to represent credentials (KafkaClientSecurity)
  • Expose a method on RedpandaService which exposes "default" credentials that are suitable to connect to the cluster: these will depend on how the cluster is configured. This is similar to the existing security_config() method (removed in this series) but using KafkaClientSecurity and supporting more server-side configuration

The primary motivation is that ducktape tests running against the cloud have SASL and TLS on by default. This is the opposite of vanilla ducktape where TLS and SASL are disabled. For existing client wrappers (and hence existing tests) to "just work" when run against the cloud, we need a consistent and expanded way for client wrappers to handle their kafka credentials.

The basic approach that client wrappers will work after this change (before this change the behavior "varied"):

  • If no authn overrides are passed in the tool constructor, we use the default kafka security config exposed by RedpandaService.kafka_security_credentials().
  • If authn information is passed to the constructor (most client wrappers offer this at least to some extend), this information overrides the relevant part of the default configuration. For example, if the username and password are passed to the client wrapper, they will override the default superuser credentials, but other default settings such as whether TLS is enabled will still be taken from the default configuration. This is implemented in a ~consistent way for all client wrappers: see KafkaSecurityCredentials.override() for details.

Backports Required

  • none - not a bug fix
  • none - this is a backport
  • none - issue does not exist in previous branches
  • none - papercut/not impactful enough to backport
  • v23.3.x
  • v23.2.x

Release Notes

  • none

Copy link
Member

@oleiman oleiman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

couple or few phrasing and bisectability nits but otherwise lgtm

tests/rptest/services/redpanda_types.py Outdated Show resolved Hide resolved
tests/rptest/services/redpanda_types.py Outdated Show resolved Hide resolved
tests/rptest/services/redpanda_types.py Outdated Show resolved Hide resolved
tests/rptest/services/redpanda_types.py Outdated Show resolved Hide resolved
tests/rptest/clients/rpk.py Show resolved Hide resolved
tests/rptest/clients/python_librdkafka.py Show resolved Hide resolved
tests/rptest/services/redpanda_types.py Show resolved Hide resolved
tests/rptest/clients/kafka_cli_tools.py Show resolved Hide resolved
tests/rptest/services/redpanda_types.py Outdated Show resolved Hide resolved
tests/rptest/services/redpanda.py Outdated Show resolved Hide resolved
@travisdowns travisdowns force-pushed the td-security-config-update branch 2 times, most recently from fd465d0 to ef43e16 Compare April 4, 2024 17:27
@travisdowns
Copy link
Member Author

fd465d0 was a pure rebase on dev.

@travisdowns
Copy link
Member Author

ef43e16 addressed a comment about a spurious override_tls which was both added and removed in this series.

oleiman
oleiman previously approved these changes Apr 4, 2024
Copy link
Member

@oleiman oleiman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

awesome stuff. thanks again for entertaining all my questions!

oleiman
oleiman previously approved these changes Apr 4, 2024
Dataclass is generally preferred over NamedTuple in python versions
where it is available. Additionally, type all the members of
SaslCredentials.
We manage a lot of kafka client security state (i.e., the auth related
stuff needed to connect to the kafka endpoint) across all our client
wrappers (and "application" wrappers like OMB) with some inconsistency
in the way we apply default configuration from the associated redpanda
service and some missing typing.

This becomes more important as we introduce mixed cloud tests as now
the default security settings are different depending on the underlying
environment: TLS and SASL is always enabled in the cloud, but is off
by default for vanilla RedpandaService.

Introduce KafkaClientSecurity which is a strongly typed class which
encapsulates these connection settings (in their simple non-SASL and
SASL variations, not stuff like oauth currently).

Expose it on RedpandaService and RedpandaServiceCloud. To be consumed
further in subsequent commits in this series.

Issue redpanda-data/core-internal#1199.
Add a very basic rpk test to cloud self test. This is relevant because
rpk (and all clients, generally) need special handling to work in the
cloud as the security settings are different.
It also needs to mock kafka_client_security() as this is used in the
RpkTool constructor. Add a class docstring.
Use KafkaClientSecurity in rpk tool in the idiomatic way we hope to do
for all clients. Basically take the default KafkaClientSecurity object
from the redpanda service and then "merge in" any explicitly specified
username, password, sasl mechanism or tls enabled settings passed into
__init__.

This merging does checks to make sure the overridden values form a
reasonable set and then exposes the associated properties which we
re-expose on RpkTool under the existing names (we no longer store them
as attributes on the class, we just store the merged KCS object).
It now type checks at basic level.
Now checks clean in standard mode.
Use KafkaClientSecurity in python_librdkafka wrapper.

Basically take the default KafkaClientSecurity object
from the redpanda service and then "merge in" any explicitly specified
username, password, sasl mechanism or tls enabled settings passed into
__init__.

This merging does checks to make sure the overridden values form a
reasonable set and then store them
as attributes on the class, rather we access them just in the merged
KCS object.
KafkaServiceAdapter wraps a Kafka install while exposing the attributes
that things like RpkTool (which expect a RedpandaService-ish) want.

We need to additionally expose kafka_client_security getter on
this wrapper as RpkTool requires it.
The default behavior already prints out the message passed to the
constructor.
Use KafkaClientSecurity in our kafka cli tools wrapper.

Basically take the default KafkaClientSecurity object
from the redpanda service and then "merge in" any explicitly specified
username, password, sasl mechanism or tls enabled settings passed into
__init__.

This merging does checks to make sure the overridden values form a
reasonable set. We only use KCS in the "non-oauth" scenario.
Types at strict level, except for datapolicy stuff which is obsolete and
will be deleted.
Remove this method from KafkaCliTools as it had a single caller which
wasn't using its unique feature (ability to specify arbitrary config).
This is a "Protocol" for python typing which has the basic functionality
a client like RpkTool or KafkaCliTools requires from RedpandaService and
similar classes.

This allows us to type the clients.
Now it type checks at pyright strict.
After the updates to KafkaCliClient, it already does the right thing
when SASL is enabled: taking its credentials from the Redpanda
service so there is no need to manually extract and pass the
credentials any more.
travisdowns and others added 10 commits April 5, 2024 13:13
To satisfy a legacy use-case in SerdeClient which requires it.
After the updates to KafkaCliClient, it already does the right thing
when SASL is enabled: taking its credentials from the Redpanda
service so there is no need to manually extract and pass the
credentials any more. Convert the schema registry tests to take
advantage by dropping the explicit configuration.

In another place SerdeClient expects a dict of configuration properties
to pass to python scripts, to we use the new to_dict method of
KafkaClientSecurity to get a dict with the expected values.
After the updates to KafkaCliClient, it already does the right thing
when SASL is enabled: taking its credentials from the Redpanda
service so there is no need to manually extract and pass the
credentials any more. Convert the panda proxy tests to take
advantage by dropping the explicit configuration.
After the updates to KafkaCliClient, it already does the right thing
when SASL is enabled: taking its credentials from the Redpanda
service so there is no need to manually extract and pass the
credentials any more.

This change converts _create_initial_topics in RedpandaTest to take
advantage by dropping the explicit configuration.
In place of the to-be-removed security_config()
Type checks cleanly at pyright strict.
Delete security_config() as there are no remaining callers.

Clients of this class should use KafkaClientSecurity instead.
SSL_SECURITY has *no* SASL

Co-authored-by: Oren Leiman <mumblemumble777@gmail.com>
Co-authored-by: Oren Leiman <mumblemumble777@gmail.com>
@travisdowns
Copy link
Member Author

Force 8710ae5 to resolve a merge conflict only.

@travisdowns travisdowns requested a review from oleiman April 5, 2024 18:54
@travisdowns travisdowns merged commit 0735cb7 into redpanda-data:dev Apr 5, 2024
16 checks passed
@dotnwat
Copy link
Member

dotnwat commented Apr 5, 2024

👏 👏 👏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants